A few thoughts on testing from the trench part2

Sep 11, 2010

    In my last blog ”A few thoughts on testing from the trench“ , i have described a scenario i gotta stumbled in . The situation is that i forgot to add cleanup method to former testcase ,which sets the tone for some intricate failures of newly added testcases.Way too nitty-gritty,let's ,say, put simply ,i just broke the prerequisites or presumptions that later test case relies on due to my carelessness. And i just come up with a solution,which just adds the cleanup to former testcases , as illustrated in following code :
[Test]
public void should_return_configed_timeframe_when_timeframe_in_app_setting_is_in_right_format()
{
 ConfigurationManager.AppSettings.Set(DateTimeHelper.TRIGGER_TIMEFRAME_KEY, "17:00:00");
 actualReturned = DateTimeHelper.ReadTimeframeFromConfig();
 expectedReturn = CreateUtcDateTimeByHHMM(17, 0);
 Assert.AreEqual(DateTimeKind.Utc, actualReturned.Kind);
 Assert.AreEqual(expectedReturn, actualReturned);

 ConfigurationManager.AppSettings.Set(DateTimeHelper.TRIGGER_TIMEFRAME_KEY, null);
 var configedTime = ConfigurationManager.AppSettings.Get(DateTimeHelper.TRIGGER_TIMEFRAME_KEY);
 Assert.IsNull(configedTime);
}
    Code between line 10 and 13 is what i thought of as a ,ah ,not bad remedy at that time. Well, it turns out that i just add more woods to "evil" fire. How can i say to myself? Man , What a miserable guy! So when Kai Ge reviews my codes ,a quick glance at those testcases , as u probably know ,the following conversation definitely blow my mind. He said ,"hey,why not put those cleanup code to TearDown() method derived from NUnit? " I said"Ah,ah,ah....." and i just gotta stuck ,period . With a astonishingly fast follow-up question ,he said,"What if any exception thrown out from your test code before your cleanup? So u just leave the testcase's "Crime Scene" ,again, uncleaned? " So that question just blows my mind with a big "Wow" from bottom of my heart. Yes ,definitely,i just write the codes without too much mediation.     But what really reveals is that it shows that how unfamiliar i am with the framework i use. So did i even know the architecture or the design philosophy behind its surface ? No , i just use it blindly and shitly , without resorting to any documentations or any tips for using that framework. Lack of specific or ,how to say ,background or backbone of tools u use may significantly slow u down and encumber your productivity dramatically.     Well ,it reminds me that Kai Ge has already talked about JUnit's design,well ,a little long ago , and i may have certain sorts of impression on that , admittedly, at that time ,not so impressive enough to let me get big "WOW" at the time i write testcases in the first place. So, i just forget it when i coded it plainly. It seems that i need to practice more to get that kinda of familiarity.     I also remember that i just see a fabulous article about how JUnit gotta be shaped by using patterns by Kent Beck. Although JUnit is simple for seasoned engineer like Kai Ge ,for me --a rookie , 'Ma Que Sui Xiao ,Wu Zang Ju Quan!(Read this in PinYin拼音) ,i think i have that kinda of need to learn . This article JUnit A Cook's Tour suits my appetite.Likewise, there is a big chapter about realizing a mini test framework like JUnit in Perl step by step in Kent Beck 's book <<Test Driven Development: By Example >>.     In JUnit A Cook's Tour Kent Beck and Erich Gamma(who is also a big cow大牛) mainly emphasize on how patterns come together to shape the whole design ,like Composite Pattern ,Template Pattern and so on. Here is a figure i referred from this article , talking about how Template Pattern gotta applied to     TestCase.run() --the core method in JUnit.      Here comes the code quoted from that article:
public void run(){
setUp();
try {
runTest();
}
catch (AssertionFailedError e) { //1

//collection test result

}
finally {
tearDown();
}

}
    This is pretty straightforward .So we know that TearDown() is put into finally block in case that when any exception thrown from runTest() method or not ,the tearDown() method is always kept committed that it will be executed. After we grasped nitty-gritty ,we ,now,are completely confident how to handle cleanup because we know how it works behind the scene.     The final solution is that we move those cleanup method to TearDown() method , so that we 're always promised the "Crime Scene" is gonna be cleaned and no messy.     So ,truth is that we need to keep informed about the tools that we use ,to some extent. Spending a little time on it ,we're probably gonna be more productive and less prone to get stumbled.     And thanks for patience and tips from Kai Ge ,i really appreciate it.