Test Driven Development provides a very structural way for agile coding. One of the steps in TDD is refactor, and this is when we improve our design, but to what extent can it still be deemed as being agile? To remind myself, I would like to write down the *only* two factors that I think are agile to drive this design step:
1) no duplicated code - if the new code is some sort of duplication of an existing logic, or it is destined to be reused by other developers in the team, I would improve the design to avoid (potential) duplication.
2) no unreadable code - if the new code is hard to read, or it makes the existing file(s) difficult to read (for example, the new code might make it harder to navigate), I would improve the design to achieve readability.
That's it. If I find myself designing due to any factors other than these two, I would feel myself being less agile. It happens a lot, sometimes due to the limitations of the technical platform, sometimes due to the "process", but I would keep reminding myself (and maybe the team) that it's not what I preferred.
There are two ways to develop software: the wrong way and the fun way.
Tuesday, August 31, 2010
Sunday, August 29, 2010
Testing private methods in RSpec
Why testing private methods? Well, it's not really about private vs public, if you want really fine granular unit tests that always only test no more than a couple of lines of code, you will need to do partial mocking and test private methods.
I heard argument that testing private methods exposes too much implementation and thus makes later refactoring harder. My argument is that unit test is part of the implementation. Fine grained "real unit" tests is very easy to read and understand. They help clarify the intent of that couple of lines of code in your target class. If you change implementation code, it should be perfect normal if you also need to change that simple unit test. On the other hand if your tests are in a larger granularity, then in each test, either you test a lot of code or your use a lot of mocking. Either case, chances are whenever you change implementation, you would need to change even more test code.
Another common practice is to extract private methods to another class and make them public and test from there. To me, there are only a few valid reasons to introduce a new class (or in general, to design), being able to test private methods isn't one of them.
Alright, with excuses all said (your argument is welcome), here is how I test private methods in ruby with rspec. I defined a global method in a file called describe_internally.rb in my test folder
then whenever I need to test private methods for a class (say Foo), I use "describe_internally Foo" instead of "describe Foo". If you prefer, you can organize these two types of tests in the same file as the below example (say Foo is a class with two methods-a public one: "kick" and a private one: "aim" which returns the target to be kicked)
(Although in this case, I would just put all specs under the describe_internally block, because the first spec also requires knowledge of the private method and from my experience there is seldom any problem caused by that)
If you need an even more fine control of the scope of where you want private methods exposed, Jay Fields wrote a blog long ago giving another approach to achieve it http://blog.jayfields.com/2007/11/ruby-testing-private-methods.html
I heard argument that testing private methods exposes too much implementation and thus makes later refactoring harder. My argument is that unit test is part of the implementation. Fine grained "real unit" tests is very easy to read and understand. They help clarify the intent of that couple of lines of code in your target class. If you change implementation code, it should be perfect normal if you also need to change that simple unit test. On the other hand if your tests are in a larger granularity, then in each test, either you test a lot of code or your use a lot of mocking. Either case, chances are whenever you change implementation, you would need to change even more test code.
Another common practice is to extract private methods to another class and make them public and test from there. To me, there are only a few valid reasons to introduce a new class (or in general, to design), being able to test private methods isn't one of them.
Alright, with excuses all said (your argument is welcome), here is how I test private methods in ruby with rspec. I defined a global method in a file called describe_internally.rb in my test folder
def describe_internally *args, &block
example = describe *args, &block
klass = args[0]
if klass.is_a? Class
saved_private_instance_methods = klass.private_instance_methods
example.before do
klass.class_eval { public *saved_private_instance_methods }
end
example.after do
klass.class_eval { private *saved_private_instance_methods }
end
end
end
then whenever I need to test private methods for a class (say Foo), I use "describe_internally Foo" instead of "describe Foo". If you prefer, you can organize these two types of tests in the same file as the below example (say Foo is a class with two methods-a public one: "kick" and a private one: "aim" which returns the target to be kicked)
describe Foo do
describe "kick" do
it "should kick at where aim is" do
foo = Foo.new
foo.should_receive(:aim).with(steve_jobs).and_return :a_place
foo.kick steve_jobs
steve_jobs.should be_kicked_at :a_place
end
end
end
describe_internally Foo do
describe "aim" do
it "should aim at where the butt is" do
Foo.new.aim(steve_jobs).should be steve_jobs.butt
end
end
end
(Although in this case, I would just put all specs under the describe_internally block, because the first spec also requires knowledge of the private method and from my experience there is seldom any problem caused by that)
If you need an even more fine control of the scope of where you want private methods exposed, Jay Fields wrote a blog long ago giving another approach to achieve it http://blog.jayfields.com/2007/11/ruby-testing-private-methods.html
Saturday, August 21, 2010
Test Driven Development on Android
Although at the very beginning, TDD, especially the UI part, looked challenging on Android, now after about 90 tests and 4,5 epic stories, I am comfortably to say that Android app can be developed in a TDD fashion reasonably smooth. You just need to accept that you can't test the interaction between UI and domain model using mock framework. Then you design in a way so that such need will be reduced to minimum. Some Android API might not be test friendly, you can solve that by introducing some middle layer abstraction.
Light Meter renamed to Photography Assistant, 1.5Beta released
I am very glad to announce that Photography Assistant 1.5 Beta was just released to the Android Market.
Features:
+ Aperture priority, Shutter priority and Manual mode for exposure setting calculation
+ Auto Exposure Value (Light Meter function) using ambient light sensor
+ Hyperfocal distance
+ Depth of Field
It was renamed from Light Meter to Photography Assistant.
Please help test this Beta version.
Features:
+ Aperture priority, Shutter priority and Manual mode for exposure setting calculation
+ Auto Exposure Value (Light Meter function) using ambient light sensor
+ Hyperfocal distance
+ Depth of Field
It was renamed from Light Meter to Photography Assistant.
Please help test this Beta version.
Tuesday, August 10, 2010
Update about Light Meter
3 weeks from the first release, Light Meter was downloaded more than 2,400 times.
The development went smooth, I just need time. Currently I am working on adding Manual and Av mode, which is going to be release 1.1. The manual mode could be helpful for the app to work with an incident light meter.
The development went smooth, I just need time. Currently I am working on adding Manual and Av mode, which is going to be release 1.1. The manual mode could be helpful for the app to work with an incident light meter.
Subscribe to:
Posts (Atom)