Neo4j and Ruby: How can I speed up unit testing? - ruby

Am starting to write unit tests along the lines of https://github.com/neo4jrb/neo4j/wiki/How-To-Test
One of the approaches there is really slow (10 seconds per test) and the other doesn't delete labels (and probably other things)
Can anyone suggest a more elaborate approach? I noticed that in the core neo4j material, the java documentation describes methods that create and tear down temporary databases, but I don't see a way to access those from the (very nice) ruby and rails neo4j gems. Perhaps via the low-level REST api? It's hard to figure out what api calls are available.

So you could probably surround your tests in transactions which is a typical approach for testing with ActiveRecord in Ruby. That might be more performant, but it should also help keep the database clean.
But you're right, the impermanent database is the tool that's provided in Neo4j for temporary databases for testing. I think that's only available if you're running JRuby, though. I did run across this, though:
https://groups.google.com/forum/#!topic/neo4j/7xeEPWEiqD0
Which links to a project which lets you start up a Neo4j server in "in memory" mode (using the impermanent database):
https://github.com/jexp/neo4j-in-memory-server
That's showing examples for Neo4j 2.0.0, so I don't know if it would work for later versions, but it might be worth a shot for your testing database.
EDIT: Another thing that I just thought of is to use the vcr gem:
https://github.com/vcr/vcr
It basically records all of the requests made to your server and then plays them back. This works great for API endpoints where result are idempotent, but if you use it for a database like Neo4j you should make sure that your tests are clearing the database before every test run so that it always starts fresh

Related

Unit Testing with Laravel

I'm using PHP with Laravel 5.5 framework.
I recently started writing unitTests for my code and I got a few questions:
What is the best way to interact with my database?
Should I use InMemoryDB like SQLite or Mock everything with Mockery.
If I have an interaction with DB than that is still unitTesting or Integration Testing?
Thank you for the answers in advence
I work in a company where we strive for 80% code coverage, in general we test mostly End-2-End, with database and mocking external calls, we use SQLite so our testsuite can run quickly in a local environment. When the case make sense, we unit tests it, as an example an Tax service i did for different countries i unit tested, because it was very input output based.
Why we prefer End-2-End:
It's quicker if you don't have to make unit, integration and end to end testing
You test the endpoint will actually will be used
I prefer to run with a real database if you are running with Continous Integration
There is drawbacks with SQLite, mainly it does not work as other RDB where there is a lot of settings and limitations, on top of my head i had problems with foreign key enforcing etc.
So to answer your question:
It's smart to use SQLite at least locally
In Unit Testing you are only testing one class and mocking everything else, you are basically testing that the code can execute. Note this is a oversimplified version on a very complex subject.

Measure performance of web application?

What are the best tools to test the performance of a (not deployed) application using Play framework? Things like, how long takes a request to execute, with different parameters, simulating a lot of requests (stress test), etc.
I'm searching a while but the problem is that the keyword "performance", "benchmarks" etc. lead me to pages about the performance of Play framework.
I thought maybe functional tests, could be used to measure performance (print difference between method start time and end...). But this doesn't look suitable for this kind of task.
I could just write a script, that triggers the requests, writes the timestamps to a log file... but maybe there's something finished, with extras, like e.g. charts, etc.
Any hint in the right direction greatly appreciated.
Iago is a load generation tool by Twitter written in Scala. Also, I've used the Loader.io addon on Heroku to do performance testing. Loader.io also has a non-heroku service that I have not used. Iago is probably your best bet for local testing of a non-public app.
A good example is a project used by Versal to choose their Scala stack for production.
The project is Scamper.

Ruby and graph DB w/o Jruby

I'm hoping to introduce a graph DB into my project w/o having to move to jRuby. As I see it, given this restriction I've got two options:
Use a graph DB that provides a RESTful interface. I don't know what impact this will have on performance. I'm planning for a crapload of data.
Find a graph DB that has a ruby interface not requiring jRuby. In my search thus far I've not found anything but most of the posts and blog entries I've found have been fairly dated. I'd prefer the DB and interface to be somewhat mature and reliable, of course.
Does anyone know of anything that would meet #2 above?
If you're concerned about performance, I'd recommend trying JRuby and neo4j.rb
because it interacts directly with the embedded, high performance neo4j-Java-API. Ultimately I think that would be the highest-performance solution.
If you're not willing to entertain JRuby at all, there are options. Neo4j has a REST API and neography is a thin wrapper for it.
Or you use the Neo4j Server - (J)Ruby extension. This is a JRuby Rack application that exposes a REST API. It contains the Neo4J server, so it can be installed and used as a JRuby app, and your stack is Ruby all the way down, even if it is mostly MRI Ruby and the JRuby part is isolated to persistence.

Testing a lot of external APIs in Rails

I'm developing a Rails app with a lot of dependencies on external APIs, for example Delicious.
All APIs share two workflows:
On the first call they are going to load all data since the beginning of time.
All following calls will load data filtered by the last execution time (if supported).
Testing them in real means I must create a test account for each API or at least use my private one. Even with VCR, because they would be called once. And my biggest problem: I would have to mess around a lot with Date's and Time's to emulate the two different workflows mentioned above. Though Timecop makes it really easy, it feels like a pain in the ass.
Another approach is to fake the API calls and their corresponding responses completely, but this means no real tests and furthermore I would never realize changes or problems with the APIs.
Any suggestions? Maybe a good combination of both ways?
Do both.
Start by mocking/stubbing everything in your regular run-frequently test suite. Do this for all the fine-grained model/controller testing.
Then add end-to-end testing (eg in integration tests) that cover usual workflow-scenarios that hit the real (test) servers.
Alternatively use a different test suite for the end-to-end testing eg cucumber instead of Test::Unit, or selenium/Watir whatever as long as it's different to your usual test suite

Database integration tests

When you are doing integration tests with either just your data access layer or the majority of the application stack. What is the best way prevent multiple tests from clashing with each other if they are run on the same database?
Transactions.
What the ruby on rails unit test framework does is this:
Load all fixture data.
For each test:
BEGIN TRANSACTION
# Yield control to user code
ROLLBACK TRANSACTION
End for each
This means that
Any changes your test makes to the database won't affect other threads while it's in-progress
The next test's data isn't polluted by prior tests
This is about a zillion times faster than manually reloading data for each test.
I for one think this is pretty cool
For simple database applications I find using SQLite invaluable. It allows you to have a unique and standalone database for each test.
However it does only work if you're using simple generic SQL functionality or can easily hide the slight differences between SQLite and your production database system behind a class, but I've always found that to be fairly easy in the SQL applications I've developed.
Just to add to Free Wildebeest's answer I have also used HSQLDB to do a similar type testing where each test gets a clean instance of the DB.
I wanted to accept both Free Wildebeest's and Orion Edwards' answers but it would not let me. The reason I wanted to do this is that I'd come to the conclusion that these were the two main ways to do it, but which one to chose depends on the individual case (mostly the size of the database).
Also run the tests at different times, so that they do not impact the performance or validity of each other.
While not as clever as the Rails unit test framework in one of the other answers here, creating distinct data per test or group of tests is another way of doing it. The level of tediousness with this solution depends on the number of test cases you have and how dependant they are on one another. The tediousness will hold true if you have one database per test or group of dependant tests.
When running the test suite, you load the data at the start, run the test suite, unload/compare results making sure the actual result meets the expected result. If not, do the cycle again. Load, run suite, unload/compare.

Resources