6.fall 23-Lecture7UnitTesting
6.fall 23-Lecture7UnitTesting
Automation
CSE 4495 - Lecture 7 - 16/08/2022
Instructor : Md. Mohaiminul Islam
1
Today’s Goals
• Unit Testing
• Testing of individual classes
• Writing and executing test cases
• How to write unit tests in JUnit.
• Executing tests as part of a build script.
Account
Some tests we might want to write:
- name • Execute constructor, verify fields.
- personnummer
- balance • Check the name, change the name, make
sure changed name is in place.
Account (name,
personnummer, Balance) • Check that personnummer is correct.
withdraw (double amount)
deposit (double amount) • Check the balance, withdraw money,
changeName(String name)
getName() verify that new balance is correct.
getPersonnummer()
getBalance() • Check the balance, deposit money,
verify that new balance is correct.
Unit Testing - Account
Account
Some potential error cases:
--name • Withdraw more than is in balance.
name
- personnummer
--balance
personnummer • Withdraw a negative amount.
- balance
• Deposit a negative amount.
Account
withdraw (name,
(double amount)
personnummer, Balance) • Withdraw/Deposit a small amount
deposit (double amount)
changeName(String
withdraw name)
(double amount) (potential rounding error)
deposit (double amount)
getName()
changeName(String
getPersonnummer() name) • Change name to a null reference.
getName()
getBalance()
getPersonnummer()
getBalance() • Can we set an “malformed” name?
• (i.e., are there any rules on a valid
name?)
Unit Testing and Test Automation
Writing a Unit Test
return sum; }
}
}
Test Fixtures - Shared Initialization
• assertEquals, assertArrayEquals
• assertFalse, assertTrue
• assertNull, assertNotNull
• assertSame,assertNotSame
assertEquals
@Test
public void testAssertEquals()
● Compares two items for
{ assertEquals("failure - strings are equality.
not ● For user-defined classes,
equal", "text", "text");
} relies on .equals method.
○ Compare field-by-field
@Test
○ assertEquals(studentA.getName(),
studentB.getName())
public void testAssertArrayEquals() rather than
{ byte[] expected = "trial".getBytes(); assertEquals(studentA, studentB)
byte[] actual = "trial".getBytes(); ● assertArrayEquals
assertArrayEquals("failure - byte arrays
not same", expected, actual); compares arrays of items.
}
assertFalse, assertTrue
@Test
public void testAssertFalse()
{ assertFalse("failure - should be
● Take in a string and a
false", boolean expression.
(getGrade(studentA, “CSE4495”).equals(“A+”)); ● Evaluates the expression
}
and issues pass/fail based on
@Test outcome.
public void testAssertTrue()
● Used to check conformance
{ assertTrue("failure - should be
true", of solution to expected
(getCGPA(studentA) > 3.5)); properties.
}
assertSame, assertNotSame
@Test
public void testAssertNotSame()
{ assertNotSame("should not be same ● Checks whether two
Object",
studentA, new Object()); objects are clones.
} ● Are these variables aliases
@Test
for the same object?
public void testAssertSame()
○ assertEquals uses
{ Student studentB = .equals().
studentA;
○ assertSame uses ==
assertSame("should be same", studentA,
studentB);
}
assertNull, assertNotNull
@Test
public void testAssertNotNull()
{ assertNotNull("should not be
● Take in an object and
null", new Object());
} checks whether it is
null/not null.
@Test ● Can be used to help
public void testAssertNull()
diagnose and void null
{ assertNull("should be null",
null);
pointer exceptions.
}
Grouping Assertions
@Test
void groupedAssertions() {
● Grouped assertions are
Person person = Account.getHolder(); executed.
assertAll("person", ○ Failures are reported
() -> assertEquals("John", together.
person.getFirstName()), ○ Preferred way to
() -> assertEquals("Doe",
compare fields of two
person.getLastName()));
data structures.
}
assertThat
@Test both - two properties must be met.
public void testAssertThat{
assertThat("albumen", both(containsString("a")).and(containsString("b")));
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }),
everyItem(containsString("n")));
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"),
equalTo("good")))); assertThat("good", anyOf(equalTo("bad"),
equalTo("good"))); assertThat(7,
not(CombinableMatcher.<Integer>
either(equalTo(3)).or(equalTo(4))));
}
assertThat
@Test everyItem - all items in list must match a
property.
public void testAssertThat{
assertThat("albumen", both(containsString("a")).and(containsString("b")));
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }),
everyItem(containsString("n")));
assertThat("godfather", allOf(equalTo("godfather"),
startsWith("go")));
assertThat("good", not(allOf(equalTo("bad"),
equalTo("good")))); assertThat("good", anyOf(equalTo("bad"),
equalTo("good"))); assertThat(7,
not(CombinableMatcher.<Integer>
either(equalTo(3)).or(equalTo(4))));
assertThat
@Test allOf - all listed properties must be true
public void testAssertThat{
assertThat("albumen", both(containsString("a")).and(containsString("b")));
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }),
everyItem(containsString("n")));
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"),
equalTo("good")))); assertThat("good", anyOf(equalTo("bad"),
equalTo("good"))); assertThat(7,
not(CombinableMatcher.<Integer>
either(equalTo(3)).or(equalTo(4))));
}
assertThat
@Test anyOf - at least one of the listed
properties must be true
public void testAssertThat{
assertThat("albumen", both(containsString("a")).and(containsString("b")));
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }),
everyItem(containsString("n")));
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"),
equalTo("good")))); assertThat("good", anyOf(equalTo("bad"),
equalTo("good"))); assertThat(7,
not(CombinableMatcher.<Integer>
either(equalTo(3)).or(equalTo(4))));
}
assertThat
@Test either - pass if one of these properties
public void testAssertThat{
assertThat("albumen", both(containsString("a")).and(containsString("b")));
assertThat(Arrays.asList("one", "two", "three"), hasItems("one", "three"));
assertThat(Arrays.asList(new String[] { "fun", "ban", "net" }),
everyItem(containsString("n")));
assertThat("good", allOf(equalTo("good"), startsWith("good")));
assertThat("good", not(allOf(equalTo("bad"),
equalTo("good")))); assertThat("good", anyOf(equalTo("bad"),
equalTo("good"))); assertThat(7,
not(CombinableMatcher.<Integer>
either(equalTo(3)).or(equalTo(4))));
}
Testing Exceptions
@Test ● When testing error
void exceptionTesting() {
Throwable exception =
handling, we expect
assertThrows( IndexOutOfBoundsExc exceptions to be thrown.
eption.class, ○ assertThrows checks
() -> { new ArrayList<Object>().get(0);} whether the code block
); throws the expected
assertEquals("Index:0, Size:0", exception.
exception.getMessage());
○ assertEquals can be
} used to check the
contents of the stack
trace.
Testing Performance
@Test
void timeoutExceeded()
{ assertTimeout( ofMillis(1
● assertTimeout can be
0), () ->
{ Order.process(); });
used to impose a time
} limit on an action.
@Test ○ Time limit stated using ofMilis(..),
void timeoutNotExceededWithMethod() { ofSeconds(..), ofMinutes(..)
○ Result of action can be captured as well,
String greeting = allowing checking of result correctness.
assertTimeout(ofMinutes(2),
AssertionsDemo::greeting);
assertEquals("Hello, World!",
greeting);
Unit Testing - Account
Account
• Withdraw money, verify balance.
@Test
- name
- personnummer public void testWithdraw_normal() {
- balance // Setup
Account account = new Account(“Test MrTest”, “19850101-1001”,
Account (name, 48.5);
personnummer, Balance) // Test Steps
withdraw (double amount) double toWithdraw = 16.0; //Input
deposit (double amount) account.withdraw(toWithdraw);
changeName(String name)
getName() double actual = account.getBalance();
getPersonnummer()
getBalance() double expectedBalance = 32.5; // Oracle
assertEquals(expected, actual); // Oracle
}
Unit Testing - Account
Account
• Withdraw a negative amount.
- name • (should throw an exception with
- personnummer
- balance appropriate error message)
@Test
public void testWithdraw_negative() {
Account (name,
personnummer, Balance) // Setup
Account account = new Account(“Test MrTest”, “19850101-1001”, 48.5);
withdraw (double amount) // Test Steps
deposit (double amount)
changeName(String name) double toWithdraw = -2.5; //Input
getName() Throwable exception = assertThrows(
getPersonnummer()
getBalance() () -> { account.withdraw(toWithdraw); } );
assertEquals(“Cannot withdraw a negative amount: -2.50”,
exception.getMessage()); // Oracle
}
Let’s take a break.
Best Practices
@Test
public void testStringUtil_Good() {
String result = stringUtil.concat("Hello ", "World");
assertEquals("Hello World", result);
}
38