Slides - CSE Buffalo

Download Report

Transcript Slides - CSE Buffalo

CSE 116/504 – Intro. To Computer Science for Majors II
LECTURE 2:
TEST-DRIVEN DEVELOPMENT
BASICS
Announcements
 CSE Distinguished Speaker Series tomorrow
 Talk will be from 3:30 – 4:30 in Student Union 201
 Dr. Wendi Heinzelman is expert in energy usage
 Discuss pioneering work on wireless & mobile networks
Announcements
 Homework problems keyed to week's lectures
 Material from Monday's lecture in problem #1
 Problem #2 on Wednesday's lecture topics & materials
 Question in problem #3 uses topics from Friday
 Can always attempt problems before its lecture
 When the topics seem difficult, do not get too worried
 Autolab up and running, so could start problems #1 & #2
Announcements
 26% of class signed up for Piazza already
 If you are not one of them, what are you waiting for?
 Several helpful discussions already underway
 This week’s recitations optional; for help on Eclipse
 Next week will be expected to create projects & use JARs
 Take advantage of opportunity to learn from the UTAs
 Especially for Mondays, please select your recitation
Today’s Goals
 Before used in grading, check TopHat works
 (Real-life TDD example to show how this helps, btw)
 Learn test-driven development goals & benefits
 Think & discuss why do we care about testing?
 How TDD differs and why it improves code quality
 Discuss what is an annotation & how used in testing
 JUnit test case basics & best practices discussed
Where Are You Located?
A. Davis 338L
B. Tropical Island
C. Norton 112
D. Baldy 21
E. Not sure
What is Your Major?
A. Comp. Sci.
B. Comp. Engineering
C. Other Engineering
D. Other Science
E. None of the above
F. Norton 112
Previous Coding Experience?
A. CSE115 only
B. CSE115 & CSE113
C. CSE115 & other
class(es)
D. CSE 115 & <1 yr work
E. CSE 115 & ≥1 yr work
F. Norton 112
Useful Code Key Concept #1
Useful Code Key Concept #1
Code that
cannot compile
Useful Code Key Concept #1
Code that
cannot compile
Good Code Key Concept #1
Good Code Key Concept #1
Good Code Works
Good Code Works
Test-Driven Development (TDD)
 Very popular technique developing software
Test-Driven Development (TDD)
 Very popular technique developing software
Test-Driven Development (TDD)
 Very popular technique developing software
 Greatly increases programmer productivity
 Happier programmers also found when using TDD
 Requires very different approach to coding
 Requires tests written BEFORE implementations
Write stubs (but no code) for class & methods
2. Knowing correct outputs, write tests to check
3. Implement methods to pass your tests (& check often)
1.
Common Objection To TDD
But…
How could I
write tests
before I know
what the
method does?
Smart Programmer Responds…
How could you
write the code
before you know
what the
method must do?
TDD Objections
 Feels weird to start with tests when you first try…
 .. but objections reflect poor programming habits
 Know method’s outcomes when starting to write…
 … but you may not know how it will be done
Thought Experiment
 Have new engine uses 100x less gas
 New power generation method provides this boost
 Of the following which test would you want:
 Belts and axels moved identically with new engine
 New engine still uses same carburetor & pistons
TDD Objections
 Feels weird to start with tests when you first try…
 .. but objections reflect poor programming habits
 Know method’s outcomes when starting to write…
 … but you may not know how it will be done
 Effects, not process, checked by good test cases
 It might be that you find faster code for method
 Other methods not rewritten as result of improvement
 Important that your tests show changes not needed
TDD Key Concept #1
Check
method’s results
NOT
method’s processes
Why TDD Helps
 Many benefits when test cases created first
 Clarify what method does so coding becomes easier
 Since written for tests, methods become easier to fix
 Know when code done by checking if tests pass
 Studies have found that TDD simplifies debugging
 Know when bug created by running tests regularly
 Tests start to fail after writing 1 line: bug on that line
 Bugs… somewhere(?) when hours pass before testing
Unit Testing Library
 Nearly everyone uses JUnit for unit testing
 Tests written in Java so can run anywhere
 Strong support that make writing tests very easy
 JUnit support in most IDEs (e.g., Eclipse, IntelliJ, BlueJ)
 Not limited to Java – xUnit exists for many languages
 Automation important to allow frequent testing
 Testing easy – just select “Run As…” “Junit test”
 Green means good – checking results also very easy
 Easy to see problems – see red when tests fail
JUnit Test Cases Format
 Most often write test class for each class
 Identical to other classes; usually named ____Test
 As a Java class, can use inheritance & have fields
 Inheritance & fields not required like any Java class
 Since ver. 4.0, JUnit’s annotations identify tests
 Extra information added to show method is test case
 Annotation added immediately before method
JUnit Test Cases Format
 Most often write test class for each class
 Identical to other classes; usually named ____Test
 As a Java class, can use inheritance & have fields
 Inheritance & fields not required like any Java class
 Since ver. 4.0, JUnit’s annotations identify tests
 Extra information added to show method is test case
 Annotation added immediately before method
No code or comments between annotation & method
Writing Test Methods
 Test methods MUST have @Test annotation
 Non-static, void methods only for JUnit to work
 By same logic, test methods cannot have parameters
 Use normal Java code to write these test methods
 Just normal methods; can contain any legal Java code
 Conditionals and loop statements often are included
 Can instantiate objects and call methods on objects
 Other methods can use assert___ & be called by tests
JUnit Annotations
 Loop until all test cases in class are executed
 JUnit executes all methods marked @Before
 Optional methods initialize any data before each test
 Run exactly 1 method labeled @Test executed
 Pass if no crashes & no incorrect asserts occur during test
 Fails & stops running when assert____ does not pass
 Executes all methods marked @After
 Also optional, cleans mess made by @Before
JUnit Annotations



method labeled @Test executed





assert____ Statements
 Java statements which actually check results:
assertTrue(boolean test)
assertFalse(boolean test)
assertEquals(X expected, X actual)
assertNull(Object objTest)
assertNotNull(Object objTest)
fail()
assert____ Statements
 Java statements which actually check results:
String message
String message
String message
String message
String message
String message
Can add
optional message.
Use it when you
have additional
information
for failing test.
Statements Performing Checks
assertEquals(
expected, X actual)
assertFalse(
@Test method
should
le exp,
doubleexecute
act,double
lean test) 1 or more
assert_____.
olean test)
assertNull(
ect objTest)
assertEquals(
assertEquals(
assertTrue(
at exp, float act, float tol)
Results only show if
assertNotNull(Object objTest)
fail()
assertion failed.
tol)
Class To Be Tested
public class Operational {
private int a, b;
public Operational(int fst, int snd) {
a = fst;
b = snd;
}
public String multiply() {
int product = a * b;
return “Product is ”+product;
}
public String sum() {
return “Sum is ”+a+b;
}
}
Class To Be Tested
public String sum() {
return “Sum is ”+a+b;
}
This concatenates a & b
(like Strings) rather than
adding them. So 3 + 2 will
be 32 and not 5.
Our tests need to find this!
Starting to Write Test Cases
 Traditionally, test class adds “Test” to class name
 Each case is method having @Test annotation
public class OperationalTest {
@Test
public void testMult0() {
Operational xByZero = new Operational(3, 0);
Operational zeroByX = new Operational(0, 17);
assertEquals(“Product is 0”, xByZero.multiply());
assertEquals(“Product is 0”, zeroByX.multiply());
}
Starting to Write Test Cases


public class OperationalTest {
@Test
public void testMult0() {
Operational xByZero = new Operational(3, 0);
Operational zeroByX = new Operational(0, 17);
assertEquals(“Product is 0”, xByZero.multiply());
assertEquals(“Product is 0”, zeroByX.multiply());
}
Starting to Write Test Cases


@Test
public void testMult0()
Operational xByZero =
Operational zeroByX =
assertEquals(“Product
assertEquals(“Product
}
{
new Operational(3, 0);
new Operational(0, 17);
is 0”, xByZero.multiply());
is 0”, zeroByX.multiply());
Bad Tests to Write
 Only get to know test failed with assertTrue()
@Test
public void yuckyButLegal() {
Operational xByOne = new Operational(-2, 1);
Operational oneByX = new Operational(1, 4);
assertTrue(xByOne.multiply()
.equals(“Product is 2”));
}
Bad Tests to Write

@Test
public void yuckyButLegal() {
Operational xByOne = new Operational(-2, 1);
Operational oneByX = new Operational(1, 4);
assertTrue(xByOne.multiply()
.equals(“Product is 2”));
}
Better Tests to Write
 Get more detailed results with assertEquals()
@Test
public void muchImproved() {
Operational xByOne = new Operational(-2, 1);
Operational oneByX = new Operational(1, 4);
assertEquals(xByOne.multiply(),
“Product is 2”);
}
Better Tests to Write

@Test
public void muchImproved() {
Operational xByOne = new Operational(-2, 1);
Operational oneByX = new Operational(1, 4);
assertEquals(xByOne.multiply(),
“Product is 2”);
}
JUnit Tests Key Concept #1
Use assertTrue()
& assertFalse()
only with boolean
variables & methods
More Test Gotchas
 Must be certain assert___ checking code to test

@Test
public void whatAmITesting() {
Operational xByOne = new Operational(-2, 1);
assertEquals(“Product is -2”,
“Product is ” + (-2 * 1));
}
More Test Gotchas


@Test
public void whatAmITesting() {
Operational xByOne = new Operational(-2, 1);
assertEquals(“Product is -2”,
“Product is ” + (-2 * 1));
}
More Test Gotchas


@Test
public void whatAmITesting() {
Operational xByOne = new Operational(-2, 1);
assertEquals(“Product is -2”,
“Product is ” + (-2 * 1));
}
More Test Gotchas
 Will this pass?

@Test
public void passingIsNotFailing() {
Operational xByOne = new Operational(-2, 1);
xByOne.sum();
}
More Test Gotchas
 Will this pass?

@Test
public void passingIsNotFailing() {
Operational xByOne = new Operational(-2, 1);
xByOne.sum();
}
More Test Gotchas
 Will this pass?

@Test
public void passingIsNotFailing() {
Operational xByOne = new Operational(-2, 1);
xByOne.sum();
}
JUnit Tests Key Concept #2
Every @Test method
should call
AT LEAST 1
assert_____()
Hardcode Your Checks
 Hardcode answer in assert___ whenever possible
@Test
public void shouldNotPassButDoesPass() {
Operational xByOne = new Operational(-2, 1);
assertEquals(“Sum is ” + -2 + 1, xByOne.sum());
}
Hardcode Your Checks
 Hardcode answer in assert___ whenever possible
@Test
public void shouldNotPassButDoesPass() {
Operational xByOne = new Operational(-2, 1);
assertEquals(
, xByOne.sum());
}
Hardcode Your Checks
 Hardcode answer in assert___ whenever possible
@Test
public void canNowFindBug() {
Operational xByOne = new Operational(-2, 1);
assertEquals(“Sum is -1”, xByOne.sum());
}
Last Detail
 Often make assumptions when writing code
 True writing code and still true writing test cases
 Passing != correct; could be no tests were run
 May not check what you think; care needed writing tests
 Tests should be written & run before coding
 Tests better fail, since code has not yet been written!
 Before wasting time, always check assumptions
Last Detail
 Often make assumptions when writing code
 True writing code and still true writing test cases
 Passing != correct; could be no tests were run
 May not check what you think; care needed writing tests
 Tests should be written & run before coding
 Tests better fail, since code has not yet been written!
 Before wasting time, always check assumptions
For Next Lecture
 Read sections 1.1 – 1.6 from textbook for Friday
 Helping review Java and knock off rust from break
 Optional recitation this week to learn Eclipse
 Useful practice, since required for homeworks & project
 Week #1 homework posted and ready to start
 Due to drop/add, this’s week due next Thursday (2/9)