What is in a test

advertisement
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
1 Test Driven Development TDD:
1.1 Where have we been?



Waterfall – Write all of the code before we do significant testing.
o What is wrong with this method?
Rational’s Unified Process (RUP) – A couple of major iterations of specify, design, develop and
test.
o Seems to work better than the Waterfall Method!
TDD – Upside down development.
o Do the test first then write the code – will this work?
1.2 Four Principles of TDD




Write the test first
Tests and compilers determine what we develop
No code goes production without full set of unit tests
Maintain the unit tests as part of the code
1.3 Unit tests are White Box tests --- Right???


What if we haven’t written the code yet are they still white box tests?
A question for the philosophers!
1.4 How do we know whether a test is exhaustive?
Famous philosophers have stated:
 “Anything that can break will break”
 “If you think you can develop fool proof code, a better fool will show up to prove you wrong”
 “If it hasn’t been tested its broken”
 Therefore, everything that can break must be tested. When in doubt, error on the “expect the
worst”.
 Start with the goal of over testing and gradually relax this level if quality stays up.
© 2011 Mike Rowe
Page 1
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
1.5 Write the Test First




When you have a task to do (a method to implement), write the test first then the code.
Don’t write all of the tests for a project then the code, but write a test for just the feature that
you are going to work on next and then implement the code and so on. Small iterations!
The emphasis is on writing a very small test and having each small test drive the development
of very small piece of code.
Then write another small test.
1.5.1 What is in a test




Setup the preconditions
Exercise the code/method
Check the post conditions
Teardown to cleanup system
1.6 No code goes production without full set of unit tests




We have a test and we have code that makes the test pass.
o It is now ready to check in and go into production.
As our system gets more complex, many of the simple methods and classes will get changed
and changed and changed –
o What happens at this point?
o They look ugly and will need to be simplified (REFACTORED)
Having all the unit tests available that correspond to each of the added bits of functionality
gives us confidence that we can rewrite the code without worrying about messing up some bit
of functionality at breaking the system.
It also lowers the risk in cleaning up code to make it more efficient, maintainable, extensible,
etc.
1.7 Wake’s Traffic light metaphor



Yellow – the test doesn’t compile  classes and methods may need to be implemented.
Red – the test compiles, but the code fails  work on the code
Green – the tests pass  check the code in and go on to the next feature.
Normal Cycle:
1. Start. (Green light!)
2. Write a test.
3. Try to run the test.
 It fails to compile, because the called routine hasn't been written yet. (Yellow light!)
© 2011 Mike Rowe
Page 2
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
4. Write a stub for the new routine.
5. Recompile the test and the stub
 It now compiles
6. Try to run the test.
It fails, because the stub doesn't do anything yet. (Red light!)
7. Write the body of the stubbed routine.
8. Recompile the test
9. Try to run the test.
It passes. (Green light again!)
Or is still needs work (Red light!) and the production code needs more work.
Eventually it will work and go to (Green light)
10. Start the cycle again.
Abnormal Conditions
From Green to Green:
The test passed right away. Either the test is bad, or you've already implemented the
feature being tested. You might consider modifying the implementation just to see the
test fail. (But see the "Refactoring" section below.)
From Green to Red:
The test failed right away. This is OK if it's a new test for an existing routine.
From Yellow to Yellow:
Oops - syntax error creating the stub. This can happen!
From Yellow to Green:
The test didn't compile without the stub, but adding the stub let the test pass. This is
very suspicious: if a do-nothing stub makes the test work, is the test valid?
From Red to Yellow:
Oops - syntax error implementing the routine. This happens a lot!
From Red to Red:
New code didn't work. This happens to everyone - just fix the code. But - if it happens a
lot, it's telling you to move to smaller tests (so you'll add smaller bits of new code as
well).
© 2011 Mike Rowe
Page 3
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
2 The Lab
We are going to use the XP process to develop a linked list class using nano-iterations to get the feel
for this process. The point of this lab is not to do some rocket science coding but to get a taste for
TDD.
2.1 Define stories
Each story defines a chunk of useful functionality. In class we will define these stories. Each story will
define a linked list feature. Rule of thumb – the story should fit on a note card.
2.1.1 Stories – What are the stores possible for a linked list class.
Each element shall consist of a node structure and the class shall consist of some of the below
operations.
 IsEmpty( ) – determines whether a list is empty or not empty -- returns bool
 Length( ) – returns the number of nodes in a list -- returns int
 AddToHead( ) – adds a node to the front of the list
 AddToTail( ) – adds a node to the tail of a list
 CeateList() – creates a new linked list.
 Find( ) – returns the index (0 based) of the first node that contains the value specified or -1 if
not found.
 GetNode( ) – returns the value stored in the specified node or Null if not found.
 DisplayNode( ) – display the node given its index
 DisplayList( ) – display the whole list
 DeleteNode( ) – deletes the specified node
 DeleteList ( ) – deletes the entire list
 SortList( ) – sorts the list by stored value.
 EditNode( ) – change the contents of a node based on node value or node index
 CopyNode( ) – copy the node at index1 to index2, if index2 is HEAD copy it to the head, if
index2 is TAIL copy it to the tail of the list.
 BinSearch( ) – binary search of a sorted list for the index of a value.
Each of these stories represents a nano-TDD iteration for the lab exercise.
Standup meetings are common in XP and other Agile-based processes. The XP lore includes standup
meetings as a mechanism for keeping meetings short and on point.
2.2 Release Planning
Define what will go into each iteration. Very high-level design, for this lab we can just produce the list
of features that we are going to implement. Some thought should go into the order in which we are
going to implement them. A particular order may help in testing and implementing.
© 2011 Mike Rowe
Page 4
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
2.3 Iteration Planning
Each XP cycle begins with iteration planning to lay out the details for the current iteration.
2.3.1 Iteration One
Based on the minimal complexity of this and subsequent iterations, iteration planning is simple. The
tasks for this iteration’s plan include:
1. Define what the test needs to do,
2. Code the test,
3. Compile the test,
4. Execute the test to guide the development of the production code, and
5. Accept the production code by checking it into the CM system.
2.3.2 Define what the Automated Unit Test needs to do
Based on the IsEmpty story, we specify the automated test to return a Boolean True when a tested
linked list is empty (contains no nodes); otherwise, it will return False. Automated tests generally
follow a pattern of setup, test, and teardown.
 For the setup, the test will need to create a linked list.
 Then it will call the IsEmpty method to see if it returns True.
 Finally, all objects created by the test are torn down by deleting the list.
2.3.2.1 We don’t want the test to do too much
Later we will need to enhance the test when we developed functionality to add and delete nodes to
and from the list. But we don’t need to do this now. We only implement enough test to get us
through the current feature’s development, and we only implement enough functionality to make the
test pass.
2.3.3 Coding of Test_IsEmpty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public bool Test_IsEmpty()
{
LinkedList list = new LinkedList();
if(list.IsEmpty())
{
Console.WriteLine("Test_IsEmpty passed");
return True;
}
else
{
Console.WriteLine("Test_IsEmpty FAILED");
return False;
}
} // End of Test_IsEmpty
© 2011 Mike Rowe
Page 5
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
2.3.4 Compilation of the Test
The Test_IsEmpty code is compiled.
 The first compilation error occurs on the third line and relates to not having a class LinkedList to
instantiate. This is a Yellow Light.
 It is the TDD practice of letting the compiler hint what code needs to be develop. The big hint is
to create the shell/stub of the class LinkedList shell.
 The XP practice of keep it simple supports the notion that we do no more than necessary to
move on to the next step.
o This may seem radical, but it does inhibit feature creep by the hands of developers.
 So as a practice of extreme TDD we implement the trivial constructor like the below:
Class LinkedList()
{
}




This Class shell is sufficient to keep the compiler happy (for now) with line three.
Compiling again produces an error on line five. We have gone from Yellow light to Yellow light,
which is not unusual.
The compiler directs us to implement the IsEmpty method of the LinkedList class.
A simple/trivial solution consists of:
public bool IsEmpty()
{
return true;
}

Compiling a third time allows the Test_IsEmpty unit test to compile.
2.3.5 Executing the test_isEmpty




Executing the Test_IsEmpty unit test returns a True, indicating that the IsEmpty functionality
exists, which is a Green light.
Initially, having a Green light might sound like we are done, but Wake [5] indicates that we
should normally go from Yellow to Red light, indicating that after the test case compiles the
execution of the test should normally fail.
Transitioning from Yellow to Green light with only the stubbed production code warns us that
we may not be testing very much. We note this and continue to the next story.
An alternative approach would be to add more teeth to the IsEmpty() method.
o But, since we haven’t needed to designed or implemented beyond this to handle the
IsEmpty() story we, as extreme TDD practitioners, would go on to the next story (linked
list feature) and revisit this test later once it is necessary to really distinguish an empty
© 2011 Mike Rowe
Page 6
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
from an non-empty list, or when there is enough design and implementation done for us
to design a Test_IsEmpty() test that can actually fail.
o When we have code that can create a non-empty list we will need to add to the
Test_IsEmpty() method.
This is the completion of the first iteration.
3 Lab Assignment
DUE: 3 Dec, NOON
Deliverables for this lab:
1) As a group implement the IsEmpty
2) Select a set of linked list features, one for each team member.
3) Have a team meeting to settle on the order of stores to implement.
4) This assignment works well with at least three people and 2 computers. One computer and two
people to do the TDD (sounds like Paired Programming); and one person and a computer to
record the journal (see point #5).
5) Use SourceSafe to coordinate your progress. Check in each time you compile!
6) After each story, have a team meeting to decide what is next.
7) Each feature shall have a different team-pair implementing. Each team member must work in
each of the roles (Pair-driver, Pair-shotgun, Journal recorder).
8) Record each compile and execution in a Tracking Sheet (see below)
 Journal progress, step by step, using the TDD method to implement the above.
 If in executing the test suite a test changes status or needs to be refactored, make sure this
work gets journalized. Remember the minimal initial IsEmpty feature!
 The errors when compiling the test case (Refer to the Traffic Light model, state the colors)
 Errors in running the test case.
9) You might want to create a driver that calls each of the tests. For instance: TestMain( ). Or use
Sharp Developer “#developer” http://www.icsharpcode.net/OpenSource/SD/
10) Deliverables:
a. A fine containing a final listing of your code (remember that the test cases are part of
your code).
b. A file containing a detailed SourceSafe history including differences!
c. The journal documenting each compile and action taken as a result of the compile.
d. A Project Report.
© 2011 Mike Rowe
Page 7
2/9/2016 2:08 AM
Lab _06--- TDD
SE 3730 / CS 5730 – Software Quality
4
Tracking Sheet
Step Roles
Story
Comments/Description
isEmpty( )
Traffic
Light
Green
1
2
isEmpty( )
Yellow
3
isEmpty( )
Yellow
5
isEmpty( )
Green
length()
Green
Wrote test_isEmpty() - did not compile – no List Class
defined  wrote a List Class stub
test_isEmpty() not compile – no isEmpty() method
wrote a isEmpty() stub
test_isEmpty() compiles and runs successfully ### did not
transition from Yellow to Red  probably implemented
trivial solution.
Start
length()
Yellow
6
Driver: Bubba
Shotgun: Bo
Recorder: Uno
Driver: Bo
Shotgun: Uno
Recorder:
Bubba
7
© 2011 Mike Rowe
Start
Wrote test_length() - did not compile – no length()
method  wrote length() stub.
Page 8
2/9/2016 2:08 AM
Download