As i wrote about in Part 1, due to the complexity and specificity of the data in my nba application, I needed a way to control and replicate the data when I run tests, while not interfering with the standard ‘wipe the test database clean’ process of Rails and RSpec when I run other tests. My theory was that I could populate the development database with a chunk of data via functionality already built (and tested) and then use the internal plumbing of both PostgreSQL and Ruby (upon which Rails is built) to put that data into a format in which I can load it into the test database only when I need it.
By the end of the previous article I had successfully figured out how to export
pg_dump -at games -t participants -t statistics -t players nba_development > spec/dumps/test.sql and import
psql -d nba_test -f spec/dumps/test.sql downloaded data from the development database to the test database. This was 2/3 of my goal originally elucidated in the beginning of the article, the third part was left to be accomplished later.
Getting desired data into the test environment.
At first, I thought this would be more complicated than it turned out to be. I figured I’d have to write some sort of helper method that I would call in my test file when needed to load the data into the test databases when I needed it. That, if you know anything about this stuff, was quite silly of me.
As it often is, the first step in trying something you’ve never tried before is to search the internet with some terms relevant to the task at hand. My search involved any way to execute command line instructions within a Ruby file. Though it shouldn’t have been surprising it turned out there was more than one way to skin this cat.
As is often the case, Stack Overflow provided me with the most clear succinct answer I could hope for. Within the various options, the one that seemed to fit me properly was the use of the
system command. So now I just had to test (as always) that the system command would work.
At first, I thought about writing a helper command that I could execute any time I wanted but then it occurred to me that if this works it’s really not a complex amount of code, and it’s not saving any time to place it in an external file, so I then thought to take advantage of the fact that all of this is built on top of ruby and I can write straight ruby in my files and have it executed properly, so I just went with the idea of including in to my test file.
As I’m trying to follow the concept of test driven development as best I can, I decided the best way to do this was to write a simple test that would pass once I had written the proper code to load the test data. The simplest way I could think of testing would be to check out the record counts of the tables that would be affected by this import. It’s a simple matter of determining what the correct record count should be. Then the test is written, without the importing aspect, so you can see that it fails, and then, as always, you make it pass, which turned out to be easier than I had originally expected.
As stated above, by the end of Part 1, I had successfully imported a sample file from the command line using the command
psql -d nba_test -f spec/dumps/test.sql. As such, making the failing tests pass was as simple as having my test file execute this command before running any of the tests. Combining what I learned previously with the Stack Overflow answer linked above, I came up with:
system 'psql -d nba_test -f spec/dumps/test.sql'.
Putting that simple one line piece of code at the top of my test file caused all those failing record count examples to pass, so I had successfully achieved the third step, in a much easier fashion than I had expected, but this was all just the preparation, for what was to come next.
What’s next you ask? Well, instead of two days worth of data I have now downloaded a months worth of data (October 28, 2015 to November 29, 2015) and will create at least one (perhaps many, one per table needed) dump file that I will use to test the actual queries I want my app to use, when I build them.
However, that is for a future article. The goal here was to get to the point where I could upload the test data while running tests, and it just took less time than I thought it would, which is a pleasant surprise, so this article will end here, probably much shorter than my previous ones, but the end goal was achieved, and that’s what counts.