Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Monday, August 15, 2011

Should You Unit Test Interaction with Static Methods?

No. You should not. Here's an example:


If you are somehow mocking this static method, you are potentially making it dangerous for other places where this static method is used. Eventually, this will create red test results that are hard to find and make your tests dependent on each other.

Tuesday, August 09, 2011

Should you unit test methods with a lot of mocking?

Well, anytime you have a lot of mocking, it is probably a smell. Particularly, a first smell is violation of the law of demeter. However, we were having discussion about whether or not we should write unit test for something like the following example:



As you can see, this method actually does a quite important task. It invokes the search method with specific parameters that will determine your search results. Now, we were debating whether or not the example unit test actually brings any value.

Here's what we have discussed:
Pros:
It confirms that you are actually calling the third party method with the right parameter.
Cons:
The test is too tightly coupled with the implementation, so it will break if something changes inside the method irrespective of its actual output.

But we failed to come to an unanimous decision on its usefulness. We all agreed on the point that it definitely needed some integration tests to make sure the search had actually worked.

Here are two questions for you:

  1. Would you skip the unit test altogether for this method and rely completely on an integration test? Why/Why not?
  2. If you are to rewrite this code, how would you write this using TDD?

Looking forward to see your input on this!

Tuesday, July 26, 2011

Constructors Are Methods, too!


Yes, if your constructor does something meaningful. This is just like another method and should be treated equally for unit testsing purpose. Here's an example that should need unit test:

It looks simple, so testing it should be simple, too. I would only skip the default constuctors, as long as they don't do anything interesting.

Wednesday, June 03, 2009

Its easier to get lost! Would you?

I was talking to a friend of mine, who started a IT start up and working full time with a few others to foster the business. He was telling me-

“We have 13 projects running at this moment. We are working our heart out. But, we are not finding any time to do Test Driven Development, Continuous Integration and all the good things…”

Well, I understand how it feels! As the title says, “Its easier to get lost!”

maze 

Do you fancy getting stuck at this maze?

For startups, it is difficult to control the pulse. Because, you want to reach your billion dollar spot as early as possible, this week, or even earlier, today or even just in a few hours! And, as days go by, you start to feel the need for some process, to safeguard your efforts and quality, to hit the deadlines, to get in the rhythm of a sustainable pace.

But it may be really difficult to catch the ball at the first jump. We, at Code71, believe we need to be visibly competent and confident about the quality of our work. And worked hard to get the gears together in motion. Now it is cliques great. We have got the people motivated to follow the best practices, the tools to “do more with less” and the process to ensure a “sustainable pace”. I advise, you do at least the following to learn to escape the maze from tomorrow-

    • DIE for planning. Plan for short spans. We plan for two week sprints.
    • While planning, estimate honestly. Estimate all the hours necessary for following best practices. (producing automated test scripts may take 40% longer time, but bear with it)
    • Plan on your inputs. You cannot push your inputs. So, you may need to squeeze the output to match against your capacity.
    • DIE to meet the deadline according to the plan.

This is the mindset. You need to start believing to sustain. You need to plan honestly and never miss a deadline. After reaching the deadline, you retrospect. Find the loopholes and start filling those one by one. If you don’t see a loophole, find a ladder to reach higher. But do not place a ladder on a land mine!

Its not difficult if you have the preparation. To prepare, at a minimum do the following-

  • Have a Continuous Integration (CI) server up and running 24x7 or DIE. (We use CruiseControl, its free and great)
  • Make your CI server to send build, test and coverage report for you. Keep an eye on the coverage report and DIE to remain well above the the 80% line.
  • Keep track of your activities for retrospect. We use ScrumPad. It helps you to iterate, collaborate and deliver.

The keyword is “sustainable pace”. I found Scrum to address this sustainable pace really smartly. If you haven’t tried yet and looking for the loopholes to fill or the ladder to climb up, I suggest you learn about agile and Scrum, find an expert and give it a try. It’s worth than you might have expected.

If you know a better way to keep delivering better, I will appreciate for sharing your idea to me.

Wednesday, May 13, 2009

Unit/Functional Test Rails ActionController filters following DRY

At ScrumPad most of our controllers are bounded by filters for authentication/authorization. Some filters apply to all actions in a controller while others apply to only a few or leave out only a few. However, since we are following TDD, we need to test the filter is invoked before each of the desired action. This makes the test code MOIST (not DRY)!

Example of Moist Code:

The following example only captures two test methods. However, if you have 30 controllers like ours and on an average 5 filters at each, you will possibly find many such duplicates making your test code so moist that it becomes shabby!

class SomeController
before_filter :authenticate
before_filter :restrict_invalid_role
end
class SomeControllerTest
def test_index_redirects_without_login
get :index
assert_redirected_to :controller=>:login, :action=>:login
end
def test_index_redirects_without_valid_role
login_as(:invalid_role)
get :index
assert_redirected_to :controller=>:exception, :action=>:not_allowed
end
end

Example of DRY Code:
I came up with the following implementation to help us with unit testing the before filters. The assumption is, if your filter is invoked, it will work fine. And we are testing the filter only once. The following code is written at the end of the test/test_helper.rb.
class ActionController::TestCase
##example: should_apply_before_filter_to_actions(:authenticate, [:index, :new])
def should_apply_before_filter_to_actions(before_filter_name, actions)
if(actions.nil? or actions.empty?)
assert false
end
filter = find_maching_before_filter(before_filter_name)
actions.each do |action|
assert_before_filter_applied(filter, action)
end
end
##example: should_apply_before_filter_to_action(:authenticate, :index)
def should_apply_before_filter_to_action(before_filter_name, action)
filter = find_maching_before_filter(before_filter_name)
assert_before_filter_applied(filter, action)
end

##example: should_not_apply_before_filter_to_actions(:authenticate, [:index, :new])
def should_not_apply_before_filter_to_actions(before_filter_name, actions)
if(actions.nil? or actions.empty?)
assert false
end
filter = find_maching_before_filter(before_filter_name)
actions.each do |action|
assert_before_filter_not_applied(filter, action)
end
end

##example: should_not_apply_before_filter_to_action(:authenticate, :index)
def should_not_apply_before_filter_to_action(before_filter_name, action)
filter = find_maching_before_filter(before_filter_name)
assert_before_filter_not_applied(filter, action)
end

##example: should_apply_before_filters([:authenticate, :session_expiry])
def should_apply_before_filters(before_filter_names)
if(before_filter_names.nil? or before_filter_names.empty?)
assert false, "No Before Filter is Passed"
end
before_filter_names.each {|filter| should_apply_before_filter(filter)}
end

##example: should_apply_before_filter(:authenticate)
def should_apply_before_filter(before_filter_name)
filter = find_maching_before_filter(before_filter_name)
if(filter.nil?)
assert false, "no matching filter found for #{before_filter_name}"
end
assert filter.options.empty?, "the filter #{before_filter_name} has only/except options and does not apply to all actions"
end

private
#finds the matching BeforeFilter object
def find_maching_before_filter(before_filter_name)
filters = @controller.class.filter_chain()
if !filters.nil?
filters.each do |filter|
if(filter.is_a?(ActionController::Filters::BeforeFilter) and filter.method == before_filter_name)
return filter
end
end
end
return nil
end

#asserts a single BeforeFilter is applied on a single action
def assert_before_filter_applied(filter, action)
if(filter.nil? or action.nil?)
assert false
end

if(filter.options.empty?)
assert true
return
end
if(!filter.options[:only].nil?)
assert filter.options[:only].include?(action.to_s)
end
if(!filter.options[:except].nil?)
assert !filter.options[:except].include?(action.to_s)
end
end

#asserts a single BeforeFilter is not applied on a single action
def assert_before_filter_not_applied(filter, action)
if(filter.nil? or action.nil?)
assert false
end

if(filter.options.empty?)
assert false
end

if(!filter.options[:except].nil?)
assert filter.options[:except].include?(action.to_s)
end
if(!filter.options[:only].nil?)
assert !filter.options[:only].include?(action.to_s)
end
end
end
Now my test code looks like the following-
  def test_filters
should_apply_before_filters(:authenticate, :restrict_invalid_role)
end
I can use the other methods as well to get finer control if the before_filter is applied using :only or :except options. And I can use these helper methods across all my controller test classes, making the whole point of testing filters really neat and short.

If you are familiar with shoulda tests, you will find the above code following shoulda like naming conventions. I found the above code to strip a lot of your efforts, since you eliminate all test codes that safeguard your filters.

Hope it helps someone with similar need.

Tuesday, April 21, 2009

Unit Test eager loading in Rails ActiveRecord association

To avoid the n+1 problem, you need to use eager loading in ActiveRecord object associations. An easy implementation of eager loading can be done using named scope in the following way.

class User < ActiveRecord::Base
has_many :friends
named_scope :eager_load_friends, :include => :fiends
end
User.find(user_id).eager_load_friends
To unit test the named scope, you can use this following helper method (keep it in test_helper.rb, if you like) that I wrote for ScrumPad
def test_eager_loaded(model, association)
assert !model.instance_variable_get("@#{association.to_s}").nil?
end
You can then test your eager loading in the following way
def test_eager_load_friends
test_eager_loaded(User.find(1), :friends)
end
You can also use the shoulda plug-in if you like. For me, I think we should test the values returned by our named scope as opposed to shoulda approach, which tests if the code is written as expected.

Got another solution? I will appreciate if you share.

Wednesday, November 26, 2008

Part 1: How am I IMPACTing following Scrum?

In a previous post in this blog, I introduced the nice little acronym IMPACT for agile. To recap, here is what IMPACT stands for -

"Iterative and Incremental development of a software by means of Merciless refactoring, Peer reviews, Automated acceptance testing, Continuous integration and of course, Test driven development"

To give you a little background around my story, let me tell you about a project that I am working since June 2006. The project is a micro-finance loan application automation server for the US financial industry. It acts as a mediator between a loan seeking customer and one of over 50 lenders in an attempt to get a loan for the customer. So, the server adds value by taking a single application to 50 odd lenders from a single submission unless no lender is left untried or some lender says 'yes' to it. This is done in real time, the processing time in average is less than 3 minutes.

Now that you have the background, let me introduce the the challenges associated with this project. The bullet points are-

  • Since this involves real dollars, there is nearly no margin for an error.
  • It processes more than a thousand loan applications per hour, so a high availability is a must.
  • This is done following agile Scrum and each two week one/two new lending partners need to be integrated.
  • The lending partners change their integration API from time to time and we need to accommodate the changes ASAP.

To address these challenges this is how we are responding-

Iterative and Incremental development (IID)

We are following Scrum and using ScrumPad to manage the IID. Basically, our clients/product owners put new requirements in terms of user stories in the product backlog at ScrumPad. So, with the prioritized product backlog we, the team, pick items to a sprint's backlog. Then as usual, we break it down to tasks and do everything that it takes to meet the deadline of two weeks. Within a sprint the following are the milestones-

Day 1 Day 2 Day 3 Day 4 Day 5 Day 6 Day 7 Day 8 Day 9 Day 10
Sprint Planning Dev & Test Dev & Test Dev & Test Dev & Test Dev & Test Dev & Test Dev & Test Test Release Production Release
  • 8th day - Sprint works are completed.
  • 9th day - Test delivery at a near production environment and feedback gathering from product owner.
  • 10th day - Incorporate feedbacks and release in production.

Note that, we generally produce a number of test releases within the first 8 days. That gives us an earlier chance to gather client feedbacks.

The beauty if this approach is, with this model in place we can release as early as in 8 working days, if not earlier. So, this helps us meeting the last two challenges as mentioned above.

Merciless refactoring

Developing incrementally offers much challenge in attaining the longevity of the product. Because, naturally as new features come in, we need to make room for that in the existing implementation.To ensure the quality and life of the product, we do merciless refactoring as we go. We have over 90% unit test coverage, which helps us in doing this continuous refactoring. So, the idea is-

  • Writing unit test and acceptance test.
  • Refactoring our code/design and validating against automated tests.

Peer reviews

This is probably the most important practice that I recommend. Because, as we had new members in the team, we found that the quality was somewhat degrading. Once, we started peer reviews, it was very helpful to the new comers as well as the veterans to keep the code quality up to the mark. We review the following things-

  • Naming of variables, methods, classes, files, namespaces etc.
  • Use of private methods for increased readability.
  • Hard coded string literals or constants.
  • Long/nested loops and long running if-else blocks.
  • Code commenting.
  • Quality of coding.

I would suggest you to try Microsoft's Stylecop, it will give you a great head start to ensure the first level code quality by enforcing the common rules. This practice is allowing us to continue the good quality over time.

I have always been shy of reading extra large text in the web. So, I thought I could better post this in two parts! I assure, next post will contain more images than texts, So, you better stay tuned for the next one...

Monday, September 01, 2008

BDD - My First BDD Code using RSpec in Ruby

I am really really happy to see people putting so much efforts for building high quality, nearly all avoidable error free software. I am a big believer of Test Driven Development and doing TDD for about two years now. I have always had the feeling that TDD is a kind of a misnomer because to some people the term 'Test' refers to finding bugs. For this very reason, when people gets started with TDD, they consider it as a waste of time to write so much extra code that doesn't necessarily find bugs!

Well, a good vocabulary always makes it more attractive and useful. Now with BDD, Behavior Driven Development, I think the vocabulary that people actually codes the behaviors and implements the behaviors, not the tests, makes it more like it.

So, lets see my first ever written RSpec ruby code and the sexy html output!

#This is a poor Stack implementation

class Stack
def initialize
@items = []
end
def push(item)
@items << item
end
def pop
return nil unless @items && @items.length > 0
item = @items.last
@items.delete item
return item
end
def peek
return nil unless @items && @items.length > 0
@items.last
end
def empty?
@items.empty?
end
end

#This is the RSpec ruby code. Isn't is Simple?

describe Stack do
before(:each) do
@stack = Stack.new
end
describe "Empty" do
it "Should be empty when created" do
@stack.empty?.should == true
end
end
describe "With One Item (value = 3)" do
before(:each) do
@stack.push(3)
end
it "should not be empty" do
@stack.empty?.should be_false
end
it "should return the item (=3) when #peek" do
@stack.peek.should == 3
end
it "should return the item (=3) when #pop" do
@stack.pop.should == 3
end
end
end

Well, we all write codes and are doing this day and night for years. What I like to see is as sexy an output as the following from my source code :-)

RSpec

I know, you liked the output. For more you may check at http://rspec.info/

Need a similar solution on .Net? Keep Googling and come back to me if you see a good BDD tool. I would really like to use BDD in my .Net projects and see how better it performs over TDD.

Sunday, August 03, 2008

Ninject - Dependency Injection Framework for .Net Objects

I loved Ninject because

- I don't love to write/edit XML documents myself.

- I think Ninject can save a lot of coding and debugging time.

- This is a cool framework :-) with a fun-to-read documentation.

- It uses simple conventions and Attributes for resolving most dependencies behind the scene.

- You can take full advantage to lambda expressions for writing compact codes.

Today, I took a look into this Ninject framework. I have used Spring.Net and Unity in my previous and current projects. But seems like Ninject has the most 'fluent vocabulary' that lets you develop on most 'fluent interfaces'.

Take a look at the fun-to-read documentation at http://dojo.ninject.org/wiki/display/NINJECT/Home and enjoy the 20 minutes while you eat the whole document!

Thursday, March 20, 2008

A solution to the problem with creating mocks for interfaces with Generic Methods with NMock

I was so happy with NMock to see how it can dynamically generate mocks of interfaces and also gives me a fluent interface to write expectations and everything it does to help me in unit testing!

However, I could not generate dynamic mocks for interfaces with Generic methods and it kept showing me the 'TypeLoadException' on and on. My interface looks like the following -

interface IObjectFactory
{
T GetObject(string id);
}

As I failed to create a mock implementation of this interface using NMock, I just wrote a mock implementation myself, which looks like the following

class MockObjectFactory: IObjectFactory
{
public Type RequestedObjectType;
public string RequestedObjectId;
public T GetObject(string id)
{
RequestedObjectType = typeof(T);
RequestedObjectId = id;
return new Mockery().NewMock();
}
}


And in my test code, just injected the above mock implementation of the IObjectFactory where needed. So, although NMock cannot handle mocking of this type of an interface now, you can actually create a mock implementation and use NMock inside the implementation to help you.

Sunday, March 16, 2008

Mock Internal Interface with NMock2 - Use InternalsVisibleToAttribute

Yesterday I badly needed to create mocks for my internal interfaces. I am using NMock2 as a Mocking framework and found it really difficult to produce Mocks for internal interfaces. After some 'google time' and investigation I found that you need the following two lines in your AssemblyInfo.cs to achieve this purpose-

[assembly: InternalsVisibleTo("Mocks")]
[assembly: InternalsVisibleTo("MockObjects")]

Where are the two assemblies? I found that these two assemblies are dynamically created by NMock2 for mocking your interfaces.

To find out the truth yourself, just put a breakpoint and watch the value of the following line-

AppDomain.CurrentDomain.GetAssemblies()

You should see the two assemblies in the list of the assemblies in the current application domain.

I found it interesting. I wish someone of you might find it useful too!

Note: You may still need to add InternalsVisibleTo attribute for your test assembly with the above two declarations.

Tuesday, March 11, 2008

Testing Internal Class in .Net C#

I have been to a situation where only a small number of classes had been declared as public classes in an assembly. And most of the classes are declared as internal, because I wanted to expose only the public classes to the consumers of my assembly.

However, doing so creates another challenge in testing the internal classes. As we most commonly want our test codes to reside on a separate assembly so that we can leave that assembly out when we are releasing the end product. And the internal access control would makes it difficult to write unit tests for these classes.

One workaround to this problem is to keep the test classes in the same assembly so that the test class has access to the internal class. However, to leave out these test classes from release configurations, we need to apply a conditional compilation for these files.

However, this is a pessimistic or short cut solution to the real problem. We actually want to test an internal class from another assembly (the test assembly) and don't want to go through reflection or other less intuitive paths.

I just found that, adding the following assembly attribute in the AssemblyInfo.cs may do the trick.

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestAssemblyName")]


Adding this attribute will make the assembly's internals visible to the assembly thats specified in the argument.

So, once this attribute is added to an assembly, the test assembly treats the internal classes just as other public ones and need not worry about access protection problems.

Sunday, December 02, 2007

The Easiest and the Hardest Methods to write unit test for

I was wondering to find out the easiest methods to write unit tests for. I came up with a few results as the following ones...

a. A method that takes no parameter, perform calculations on only local data and always returns a constant value is the easiest to test. But the question is, is this at all important to have such methods?

b. A method that takes some parameters, and limits its operations only on the supplied parameters and local variables and returns some value or throws exception is also very easy to write a test for.

Now, we want all our methods to be easily unit testable. But the reality is, we cannot always have the most convenient forms for unit testing with real life methods.

And things start to go wrong as we have deviations from the ideal. Some of the most commonly found deviations are -
1. void methods that optionally throws exception
2. void methods without exceptions
3. Methods without parameters.
4. Methods having multilevel nesting and complex flow.
5. Methods that depends on other methods or classes or modules.
6. Methods having dependency on static methods.
7. Methods with a risk of runtime exception.

I will be posting rescue scenarios with appropriate reasoning to get around to the discomforts of the above listed deviations from ideal unit testing perspectives.

Stay tuned to get more on this...:-)

Unit Testing void Methods - Part 1

Dissection of void Methods without parameters

Methods with void return types incur complexities in writing unit tests. So, we need to characterize the void methods to make sure we have guards against the odds for testability.

A typical void method without any parameter looks like the following

public void DoSomething()
{

//1.modifies some member variables
this.someMemberVariable = 10;

//2.Calls methods of the same class or other classes
someClass.SomeOtherMethod(someArg);

//3.Sometimes throws exception
}


So, we need to make sure we can test all the activities performed by such a method. The following are the illustrative examples showing the unit test solutions case by case

a. To test a method that modifies a member variable we need to write assertions on the member variables accessors. If this is a private member without a getter method then we will overlook it for the same reason as we discard the testing of private members

Note: Examples coming up shortly.

b. If this method calls a method from this class, we need to make sure that the called method is tested. If the called method belongs to anther class then, we can use dependency injection to use a mock for this method or make sure this method is testable.

Note: Examples coming up shortly.

c. If a method throws exception on some certain conditions, we can test for that exception with the appropriate conditions.

Note: Examples coming up shortly.