Creating a unit test suite using Rspec and Factory Girl - ruby

I have a requirement where we should be creating for Factories for servers, we call them as Vservers. It basically has the attributes like Fully qualified domain name (fqdn), eg: dev-vserver.storage.com, ID and etc..
We make a connection to the Vserver and retrieve information about different operations that we do like provisioning storage, resizing of volumes, deletion of volumes etc., in a json format.
We would like to come up with a better unit testing environment with RSPEC and FactoryGirl, where we can mock the Vserver functionality by creating doubles or mocks instead of directly interacting with the actual Vserver for testing.
I would like to hear suggestions and opinions from all you.
Help is much appreciated.
Thanks,
Mahesh

So from what I gather, you want to use mocks or test doubles to mimic the functionality of your Vservers. This is indeed possible, the question is should it be done.
You can use factory girl to create factories for each of your Vserver classes, but those facotories will only return whatever data you give them, they wont have any real data, since they only have whatever you assigned them in your tests or factories.
What I would recommend is that within your facotries, you actually establish a connection to each instance of your Vservers, and pull back all the attributes which you need. So for example you could create a factory like so:
factory :vserver_1 do
id { connect_to_vserver_1_and_get_id }
domain_name { connect_to_vserver_1_get_domain_name }
end
This would instantiate a new instance of vserver_1, with all the attributess of your current vserver. If you were to change the domain name of verserver 1 in the future, your vserver_1 factory would reflect these changes.
Also, the factory girl gem has great docs, you should definitely read them in their entirety before building a new test suite. Good luck!

Related

Running Multiple Factories of the Same Object in Production

At work, we're using Ruby 2.3.4, Rails 4.2.7, and FactoryGirl 4.0.0. We've run into the problem of having way too many traits in our base factories. We've started a project for replacing them and have a pattern in mind, but we need to be able to incrementally add our new factories to our production code while the original factories remain active.
Are there any reasonable ways to get this done?
This question, Running two spec folders in Rails with RSpec, seems to have the same problem, but separate branches is not a feasible solution for us.
The first example here might be what you're looking for.
On one of the latest versions of factory-bot, you can set up concurrent factories like this:
factory :orignal_class do
text 'original text'
end
factory :new_class_factory, class: OriginalClass do
text 'this will be used instead when creating new_class_factory'
end
When you invoke the second factory, it will still be of the same class as the first factory, but will instead use the fields defined in its factory over the original factory.

How do I completely avoid using a database in RSpec tests?

I want to use FactoryGirl to build in-memory stubs of models, then have all ActiveRecord queries run against only those. For example:
# Assume we start with an empty database, a Foo model,
# and a Foo factory definition.
#foo_spec.rb
stubbed_foo = FactoryGirl.build_stubbed(:foo)
# Elsewhere, deep in the guts of application
Foo.first() # Ideally would return the stubbed_foo we created
# in the test. Currently this returns nil.
The solution might be to use an in-memory database. But is the above scenario possible?
If your reason for avoiding the database, is to speed up your tests, then there are better ways.
Use FactoryGirl.build as much as possible instead of create. This works as long as the record won't be fetched from the database by your code. This works well for unit tests with well-structured code. (For example, it helps to use Service Objects and unit test them independently.
For tests that actually need to read from the database (as in your Foo.first example call), you can use FactoryGirl.create and use transactional fixtures. This creates a database transaction at the beginning of each test example, and then rolls back the transaction at the end of the example. This can cause problems when you use callbacks in your ActiveRecord models such as after_commit.
If you use after_commit or other callbacks in your models that require the database transaction to close (or you use explicit transactions in your code), I recommend setting up DatabaseCleaner. Here's an example of to configure and use it: https://gist.github.com/RobinDaugherty/9f4e5f782d9fdbe191a23de30ad8b539

TDD: why, how and real world test driven code

First, Please bear with me with all my questions. I have never used TDD before but more and more I come to realize that I should. I have read a lot of posts and how to guides on TDD but some things are still not clear. Most example used for demonstration are either math calculation or some other simple operations. I also started reading Roy Osherove's book about TDD. Here are some questions I have:
If you have an object in your solution, for instance an Account class, what is the benefit of testing setting a property on it, for example an account name, then you Assert that whatever you set is right. Would this ever fail?
Another example, an account balance, you create an object with balance 300 then you assert that the balance is actually 300. How would that ever fail? What would I be testing here? I can see testing a subtraction operation with different input parameters would be more of a good test.
What should I actually test my objects for? methods or properties? sometime you also have objects as service in an infrastructure layer. In the case of methods, if you have a three tier app and the business layer is calling the data layer for some data. What gets tested in that case? the parameters? the data object not being null? what about in the case of services?
Then on to my question regarding real life project, if you have a green project and you want to start it with TDD. What do you start with first? do you divide your project into features then tdd each one or do you actually pick arbitrarily and you go from there.
For example, I have a new project and it requires a login capability. Do I start with creating User tests or Account tests or Login tests. Which one I start with first? What do I test in that class first?
Let's say I decide to create a User class that has a username and password and some other properties. I'm supposed to create the test first, fix all build error, run the test for it to fail then fix again to get a green light then refactor. So what are the first tests I should create on that class? For example, is it:
Username_Length_Greater_Than_6
Username_Length_Less_Than_12
Password_Complexity
If you assert that length is greater than 6, how is that testing the code? do we test that we throw an error if it's less than 6?
I am sorry if I was repetitive with my questions. I'm just trying to get started with TDD and I have not been able to have a mindset change. Thank you and hopefully someone can help me determine what am I missing here. By the way, does anyone know of any discussion groups or chats regarding TDD that I can join?
Have a look at low-level BDD. This post by Dan North introduces it quite well.
Rather than testing properties, think about the behavior you're looking for. For instance:
Account Behavior:
should allow a user to choose the account name
should allow funds to be added to the account
User Registration Behavior:
should ensure that all usernames are between 6 and 12 characters
should ask the password checker if the password is complex enough <-- you'd use a mock here
These would then become tests for each class, with the "should" becoming the test name. Each test is an example of how the class can be used valuably. Instead of testing methods and properties, you're showing someone else (or your future self) why the class is valuable and how to change it safely.
We also do something in BDD called "outside-in". So start with the GUI (or normally the controller / presenter, since we don't often unit-test the GUI).
You already know how the GUI will use the controller. Now write an example of that. You'll probably have more than one aspect of behavior, so write more examples until the controller works. The controller will have a number of collaborating classes that you haven't written yet, so mock those out - just dependency inject them via an interface. You can write them later.
When you've finished with the controller, replace the next thing you've mocked out in the real system by real code, and test-drive that. Oh, and don't bother mocking out domain objects (like Account) - it'll be a pain in the neck - but do inject any complex behavior into them and mock that out instead.
This way, you're always writing the interface that you wish you had - something that's easy to use - for every class. You're describing the behavior of that class and providing some examples of how to use it. You're making it safe and easy to change, and the appropriate design will emerge (feel free to be guided by patterns, thoughtful common sense and experience).
BTW, with Login, I tend to work out what the user wants to log in for, then code that first. Add Login later - it's usually not very risky and doesn't change much once it's written, so you may not even need to unit-test it. Up to you.
Test until fear is replaced by boredom. Property accessors and constructors are high cost to benefit to write tests against. I usually test them indirectly as part of some other (higher) test.
For a new project, I'd recommend looking at ATDD. Find a user-story that you want to pick first (based on user value). Write an acceptance test that should pass when the user story is done. Now drill down into the types that you'd need to get the AT to pass -- using TDD. The acceptance test will tell you which objects and what behaviors are required. You then implement them one at a time using TDD. When all your tests (incl your acc. test) pass - you pick up the next user story and repeat.
Let's say you pick 'Create user' as your first story. Then you write examples of how that should work. Turn them into automated acceptance tests.
create valid user -> account should be created
create invalid user ( diff combinations that show what is invalid ) -> account shouldn't be created, helpful error shown to the user
AccountsVM.CreateUser(username, password)
AccountsVM.HasUser(username)
AccountsVM.ErrorMessage
The test would show that you need the above. You then go test-drive them them out.
Don't test what is too simple to break.
getters and setters are too simple to be broken, so said, the code is so simple that an error can not happen.
you test the public methods and assert the response is as expected. If the method return void you have to test "collateral consequences" (sometimes is not easy, eg to test a email was sent). When this happens you can use mocks to test not the response but how the method executes (you ask the mockk if the Class Under Test called him the desired way)
I start doing Katas to learn the basics: JUnit and TestNG; then Harmcrest; then read EasyMock or Mockito documentation.
Look for katas at github, or here
http://codekata.pragprog.com
http://codingdojo.org/
The first test should be the easiest one! Maybe one that just force you to create the CUT (class under test)
But again, try katas!
http://codingdojo.org/cgi-bin/wiki.pl?KataFizzBuzz

Factory Girl - what's the purpose?

What's the purpose of Factory Girl in rspec tests when I could use before(:each) blocks? It feels like the only difference between Factory Girl and a before(:each) is that the factory prepares object creation outside of the test. Is this right?
Gems like Factory Girl and Sham allow you to create templates for valid and re-usable objects. They were created in response to fixtures which where fixed records that had to be loaded into the database. They allow more customization when you instantiate the objects and they aim to ensure that you have a valid object to work with. They can be used anywhere in your tests and in your before and after test hooks.
before(:each), before(:all), after(:each) and after(:all) all aim to give you a place to do setup and teardown that will be shared amongst a test group. For example, if you are going to be creating a new valid user for every single test, then you'll want to do that in your before(:each) hook. If you are going to be clearing some files out of the filesystem, you want to do that in a before hook. If your tests all create a tmp file and you want to remove it after your test, you'll do that in your after(:each) or after(:all) hook.
The ways these two concepts differ is that Factories are not aimed at creating hooks around your tests, they are aimed at creating valid Ruby objects and records, so that you can keep your object creation flexible and DRY. Before and after hooks are aimed at setup and teardown tasks that are shared in an example group so that you can keep your setup and teardown code DRY.
FactoryGirl replaces fixtures in tests. This way, you won't have to keep the fixtures up-to-date as you change the data model. Fixtures can also tend to get unwieldy as you add more edge cases.
FactoryGirl generates data on the fly and adding and removing fields is much easier. Also, you can use it in setup just how you'd use fixtures.
Does that make it clearer?
also fixture definitions are global across your entire application. Factories can be local - so data specific to a isolated test case is in the setup for that particular context and not in a single global fixtures file.
This book covers the subject very well if you want some more reading matter

Test driven development: Inversion of Control (IOC)

I googled and read some good answers/posts on IOC and do understand the overall concept. I have an existing framework (not very well designed) and TDD is an after thought to write some NUNIT test fixtures. Can I use IOC on an existing code base with out changing the existing code base? Or IOC is used when we are designing application from scratch?
I use this technique for converting legacy code to dependency injected beauty:
If I create just one object for a class, make it a field and create it in the constructor.
If I create more than one object, make a factory for that object and create the factory in the constructor.
Put interfaces on the objects (I like the "IDoThisForYou" style as it allows me to understand the roles of classes easily, but whatever works for you).
Cascade the constructors - make one constructor new up the objects and pass them into the other by the interface.
Now you can mock and DI the interfaces in your tests. The actual cascade is simple enough that you can get by with inspection. Eventually you'll get to the point where you can use a container and then you'll delete the first constructor; this is an easy first step towards that.
(Don't mock out domain objects with heavy data - it's not worth it.)
Good luck!
It doesn't have to be from scratch, but obviously you would structure things to allow IOC to be pretty painless if you did,
But it can be patched in.... depending on how decoupled your system is, that may or may not be a big job. Essentially its an object creation pattern, so it only effect the points of creation.... if thats done willy nilly all over the place, then it will take a bit of clean up.
I'd start with getting unit tests in place first. Worry about IOC as a second concern, its not actually needed to do TDD

Resources