SlideShare a Scribd company logo
Effective Unit Test
Style Guide
- Jacky Lai
Table of Contents
1. What NOT to Unit Test
2. What to Unit Test then?
3. Criteria of a Good Unit Test
4. Unit Test Method Name
5. Unit Test Content
1. What NOT to Unit Test
u Before we delve into this style guide, we need to know what not to unit test.
"What not to test" is very important because any unnecessary test code in our
code base will create noise in our code base and increase our maintenance
cost.
u We can roughly divide all classes into 3 types: Entity, Control, Boundary
(http://www.cs.sjsu.edu/~pearce/modules/patterns/enterprise/ecb/ecb.ht
m).
u Entity - Data Container, e.g. DTO
u Boundary - Classes that communicate directly to external services, via network
connection, e.g. REST API, DAO, HttpClient, MessageHandler etc.
u Control - Classes that normally make decision.
Fig 1. Unit test and CBE
u Out of these 3 types of classes, in general, we don't need to write unit test
for:
u Entity – Since it contains only logic-less getters and setters method, there is no
value in testing all these getters / setters.
u Boundary - We need to cover boundary class with integration test, we just don't
need to write unit test for it. If you need to unit test it just because your boundary
class (handler class etc.) contains processing logic, you probably need to delegate
the processing logic into control class.
u There are some exceptions for the rules above. We may need to write unit
test for the following conditions:
u If the Entity class has validation rules. We need unit test validation logic.
u If the Boundary class has event broadcasting capability, as the example below. We
need to verify that new event is being broadcasted.
u publishEvent(new DataUpdatedEvent()); // example
2. What to Unit Test then?
u Control - It makes decision, it has processing logic inside. It's like our brain.
We need to make sure it's processing logic is correct and yield correct output.
3. Criteria of a Good Unit Test
u A good unit test satisfy 3 criteria:
1. Test a single feature in isolation.
2. Easy to understand by other engineers.
3. Help to identify issue effectively during test failure.
u Most unit tests satisfy #1. This styling guide will focus on #2 and #3.
4. Unit Test Method Name
u A test method name should consist of
<targetMethod>_<expectedResult>_<initialState>.
u Example:
@Test
public void computeTotalWidth_shouldReturnTotalWidth_givenPositiveNumbers() {…}
@Test
public void computeTotalWidth_shouldThrowException_givenNegativeNumbers() {…}
@Test
public void generate_shouldGenerateXYZ_forABConly() {…}
method_expectedResult_initialState()
naming style
testTargetMethod()
naming style
u Engineers can fix test failures with confidence if they understand what is the
correct behavior of the code.
u Code reviewers on the other hand can easily spot on any missing test cases.
u As a side benefit, this naming style help programmer to keep his/her mind
flowing when he/she is writing the test. For example, when he/she is stuck at
what to test, he/she can think out loud saying "this method should return
something when xyz is given”.
u In contrast, using names like “testComputeTotalWidth()” gives less context
about it’s intent.
5. Unit Test Content
1. We use AAA style where every unit test has 3 sections - Arrange, Act,
Assert:
u Arrange - Set up initial state (this will normally occupy more than 80% of your test
code)
u Act - Perform action
u Assert - Verify the result
2. It is important to clearly identify these three sections with
comments, allowing us to quickly jump between the “arrange", "act" and
"assert" sections.
3. We use SUT (System Under Test) to denote target instance.
u This helps us identify the target instance from a swarm of mock objects.
✔️Do this
@Test
public void testSearch_shouldReturnTargetIndex_ifFoundInInputValues() {
// 1. arrange
List<Integer> sortedNumbers = Arrays.asList(1, 2, 3);
int targetValue = 2;
BinarySearcher sut = new BinarySearcher();
// 2. assert
int targetIndex = sut.search(sortedNumbers, targetValue);
// 3. assert
Assertions.assertThat(targetIndex).isEqualTo(1);
}
✔️ AAA Pattern
@Test
public void test() {
// 1. arrange
final int TARGET_VALUE = 2;
Node node1 = new Node(8);
Node node2 = new Node(4);
Node node3 = new Node(5);
Node node4 = new Node(3);
Node node5 = new Node(9);
Node node6 = new Node(2);
node1.addChildNode(node2);
node1.addChildNode(node3);
node3.addChildNode(node4);
node1.addChildNode(node5);
node5.addChildNode(node6);
BFSearcher sut = new BFSearcher();
// 2. act
Node node = sut.search(node1, TARGET_VALUE);
// 3. assert
Assertions.assertThat(node).isEqualTo(node6);
}
❌ Without AAA Patter
@Test
public void test() {
final int TARGET_VALUE = 2;
Node node1 = new Node(8);
Node node2 = new Node(4);
Node node3 = new Node(5);
Node node4 = new Node(3);
Node node5 = new Node(9);
Node node6 = new Node(2);
node1.addChildNode(node2);
node1.addChildNode(node3);
node3.addChildNode(node4);
node1.addChildNode(node5);
node5.addChildNode(node6);
BFSearcher sut = new BFSearcher();
Node node = sut.search(node1, TARGET_VALUE);
Assertions.assertThat(node).isEqualTo(node6);
}
u AAA Pattern:
u The Arrange section of AAA takes up over 80% of the code in our test, but we can
still easily jump to Act sections by looking at the comments.
u ”sut" naming makes the test target stand out.
u Without AAA Pattern
u We have to start reading the code from beginning.
u Test target buried in the sea of mock objects.
1. A test should be self-contained. We want to understand the code fast. We
don't want to jump around different methods to understand the test flow.
u It is preferred that you do not follow the DRY (Don't Repeat Yourself) principle.
Striving for code reuse will lead to tightly coupled and inflexible test, which
discourages refactoring.
❌ Don’t do this
// Do not do this. Code reader has to scroll
// up and down to understand the whole test logic.
@Test
public void testXYZ(){
// 1. arrange
setup1();
setup2();
doSomething();
Target sut = new Target();
// 2. act
actualResult = sut.doSomething();
// 3. assert
Asserts.assertThat(222, actualResult);
}
private void setup1(){ … }
private void setup2(){ … }
private void doSomething(){ … }
The End.

More Related Content

PPT
Md04 flow control
PPT
Krazykoder struts2 interceptors
PDF
C++ Unit Test with Google Testing Framework
PPTX
TestNG vs Junit
PPT
Junit4.0
PDF
FunctionalInterfaces
PDF
Unit testing with Junit
PPTX
Control structures in java
Md04 flow control
Krazykoder struts2 interceptors
C++ Unit Test with Google Testing Framework
TestNG vs Junit
Junit4.0
FunctionalInterfaces
Unit testing with Junit
Control structures in java

What's hot (20)

PDF
Control structures in Java
PPTX
Pi j1.3 operators
PPT
3 j unit
PPTX
Introduction to JUnit
PPSX
PPT
Junit and testNG
PPT
PPTX
TestNG Session presented in PB
PDF
1z0-808-certification-questions-sample
PPTX
TestNG Framework
PPTX
Test ng tutorial
PPTX
Testers guide to unit testing
PPTX
TestNG with selenium
PPTX
Chapter 2 : Programming with Java Statements
PPTX
Junit mockito and PowerMock in Java
PPT
PDF
TestNG - The Next Generation of Unit Testing
PDF
TestNG vs. JUnit4
Control structures in Java
Pi j1.3 operators
3 j unit
Introduction to JUnit
Junit and testNG
TestNG Session presented in PB
1z0-808-certification-questions-sample
TestNG Framework
Test ng tutorial
Testers guide to unit testing
TestNG with selenium
Chapter 2 : Programming with Java Statements
Junit mockito and PowerMock in Java
TestNG - The Next Generation of Unit Testing
TestNG vs. JUnit4
Ad

Viewers also liked (18)

PDF
Momin Resume V4
DOCX
Report-FrenchVillEdge
PDF
Current Resume, 2016
PDF
bgsu1349900740
DOCX
understand challenges for infrastructure
PDF
Curriculum Vitae - Sharon G Naidoo June 2016
PDF
Front End development workflow
PDF
Writing Tests Effectively
PDF
PostgreSQL Day italy 2016 Unit Test
PPTX
Unit Test Lab - Why Write Unit Tests?
PDF
How to write Testable Javascript
PPTX
Web based automation testing on Node.js environment
PPTX
Selenium Automation Like You’ve Never Seen!
PPTX
Continuous Delivery With Selenium Grid And Docker
PPT
Selenium
PPTX
Selenium Tutorial For Beginners | What Is Selenium? | Selenium Automation Tes...
PPT
Selenium ppt
PDF
Automated Web Testing using JavaScript
Momin Resume V4
Report-FrenchVillEdge
Current Resume, 2016
bgsu1349900740
understand challenges for infrastructure
Curriculum Vitae - Sharon G Naidoo June 2016
Front End development workflow
Writing Tests Effectively
PostgreSQL Day italy 2016 Unit Test
Unit Test Lab - Why Write Unit Tests?
How to write Testable Javascript
Web based automation testing on Node.js environment
Selenium Automation Like You’ve Never Seen!
Continuous Delivery With Selenium Grid And Docker
Selenium
Selenium Tutorial For Beginners | What Is Selenium? | Selenium Automation Tes...
Selenium ppt
Automated Web Testing using JavaScript
Ad

Similar to Effective Unit Test Style Guide (20)

PPTX
Advance unittest
PDF
How to improve your unit tests?
ODP
Effective unit testing
PPTX
TDD Best Practices
PPT
05 junit
PPT
An insight to test driven development and unit testing
PPTX
UNIT TESTING PPT
PPTX
Unit Testing in Java
PDF
Unit Testing in Software Development: Why It Matters and How to Do It Right
PDF
How and what to unit test
PPTX
Unit testing
PDF
Unit testing best practices with JUnit
PDF
Agile Work Quality: Test Driven Development and Unit Tests
PDF
How to write clean tests
PPTX
Unit testing
PDF
Unit testing with JUnit
PDF
Unit testing, principles
PDF
Sustainable TDD
PDF
unit_tests_tutorial
Advance unittest
How to improve your unit tests?
Effective unit testing
TDD Best Practices
05 junit
An insight to test driven development and unit testing
UNIT TESTING PPT
Unit Testing in Java
Unit Testing in Software Development: Why It Matters and How to Do It Right
How and what to unit test
Unit testing
Unit testing best practices with JUnit
Agile Work Quality: Test Driven Development and Unit Tests
How to write clean tests
Unit testing
Unit testing with JUnit
Unit testing, principles
Sustainable TDD
unit_tests_tutorial

More from Jacky Lai (6)

PDF
Searching and reporting with splunk 6.x e learning
PDF
Using splunk 6.4 e learning
PDF
Apache hadoop2xdeveloperjava
PDF
0536 lai
PPTX
Cache invalidation
PPTX
Simplify Complex Query with CQRS
Searching and reporting with splunk 6.x e learning
Using splunk 6.4 e learning
Apache hadoop2xdeveloperjava
0536 lai
Cache invalidation
Simplify Complex Query with CQRS

Recently uploaded (20)

PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
System and Network Administration Chapter 2
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
L1 - Introduction to python Backend.pptx
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Digital Strategies for Manufacturing Companies
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
Introduction to Artificial Intelligence
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
Nekopoi APK 2025 free lastest update
Navsoft: AI-Powered Business Solutions & Custom Software Development
System and Network Administration Chapter 2
Understanding Forklifts - TECH EHS Solution
Odoo Companies in India – Driving Business Transformation.pdf
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
How to Migrate SBCGlobal Email to Yahoo Easily
L1 - Introduction to python Backend.pptx
Design an Analysis of Algorithms II-SECS-1021-03
How to Choose the Right IT Partner for Your Business in Malaysia
Reimagine Home Health with the Power of Agentic AI​
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Audit Checklist Design Aligning with ISO, IATF, and Industry Standards — Omne...
PTS Company Brochure 2025 (1).pdf.......
Digital Strategies for Manufacturing Companies
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Introduction to Artificial Intelligence
wealthsignaloriginal-com-DS-text-... (1).pdf
Nekopoi APK 2025 free lastest update

Effective Unit Test Style Guide

  • 1. Effective Unit Test Style Guide - Jacky Lai
  • 2. Table of Contents 1. What NOT to Unit Test 2. What to Unit Test then? 3. Criteria of a Good Unit Test 4. Unit Test Method Name 5. Unit Test Content
  • 3. 1. What NOT to Unit Test u Before we delve into this style guide, we need to know what not to unit test. "What not to test" is very important because any unnecessary test code in our code base will create noise in our code base and increase our maintenance cost.
  • 4. u We can roughly divide all classes into 3 types: Entity, Control, Boundary (http://www.cs.sjsu.edu/~pearce/modules/patterns/enterprise/ecb/ecb.ht m). u Entity - Data Container, e.g. DTO u Boundary - Classes that communicate directly to external services, via network connection, e.g. REST API, DAO, HttpClient, MessageHandler etc. u Control - Classes that normally make decision.
  • 5. Fig 1. Unit test and CBE
  • 6. u Out of these 3 types of classes, in general, we don't need to write unit test for: u Entity – Since it contains only logic-less getters and setters method, there is no value in testing all these getters / setters. u Boundary - We need to cover boundary class with integration test, we just don't need to write unit test for it. If you need to unit test it just because your boundary class (handler class etc.) contains processing logic, you probably need to delegate the processing logic into control class.
  • 7. u There are some exceptions for the rules above. We may need to write unit test for the following conditions: u If the Entity class has validation rules. We need unit test validation logic. u If the Boundary class has event broadcasting capability, as the example below. We need to verify that new event is being broadcasted. u publishEvent(new DataUpdatedEvent()); // example
  • 8. 2. What to Unit Test then? u Control - It makes decision, it has processing logic inside. It's like our brain. We need to make sure it's processing logic is correct and yield correct output.
  • 9. 3. Criteria of a Good Unit Test u A good unit test satisfy 3 criteria: 1. Test a single feature in isolation. 2. Easy to understand by other engineers. 3. Help to identify issue effectively during test failure. u Most unit tests satisfy #1. This styling guide will focus on #2 and #3.
  • 10. 4. Unit Test Method Name u A test method name should consist of <targetMethod>_<expectedResult>_<initialState>. u Example: @Test public void computeTotalWidth_shouldReturnTotalWidth_givenPositiveNumbers() {…} @Test public void computeTotalWidth_shouldThrowException_givenNegativeNumbers() {…} @Test public void generate_shouldGenerateXYZ_forABConly() {…}
  • 12. u Engineers can fix test failures with confidence if they understand what is the correct behavior of the code. u Code reviewers on the other hand can easily spot on any missing test cases. u As a side benefit, this naming style help programmer to keep his/her mind flowing when he/she is writing the test. For example, when he/she is stuck at what to test, he/she can think out loud saying "this method should return something when xyz is given”. u In contrast, using names like “testComputeTotalWidth()” gives less context about it’s intent.
  • 13. 5. Unit Test Content 1. We use AAA style where every unit test has 3 sections - Arrange, Act, Assert: u Arrange - Set up initial state (this will normally occupy more than 80% of your test code) u Act - Perform action u Assert - Verify the result 2. It is important to clearly identify these three sections with comments, allowing us to quickly jump between the “arrange", "act" and "assert" sections. 3. We use SUT (System Under Test) to denote target instance. u This helps us identify the target instance from a swarm of mock objects.
  • 14. ✔️Do this @Test public void testSearch_shouldReturnTargetIndex_ifFoundInInputValues() { // 1. arrange List<Integer> sortedNumbers = Arrays.asList(1, 2, 3); int targetValue = 2; BinarySearcher sut = new BinarySearcher(); // 2. assert int targetIndex = sut.search(sortedNumbers, targetValue); // 3. assert Assertions.assertThat(targetIndex).isEqualTo(1); }
  • 15. ✔️ AAA Pattern @Test public void test() { // 1. arrange final int TARGET_VALUE = 2; Node node1 = new Node(8); Node node2 = new Node(4); Node node3 = new Node(5); Node node4 = new Node(3); Node node5 = new Node(9); Node node6 = new Node(2); node1.addChildNode(node2); node1.addChildNode(node3); node3.addChildNode(node4); node1.addChildNode(node5); node5.addChildNode(node6); BFSearcher sut = new BFSearcher(); // 2. act Node node = sut.search(node1, TARGET_VALUE); // 3. assert Assertions.assertThat(node).isEqualTo(node6); } ❌ Without AAA Patter @Test public void test() { final int TARGET_VALUE = 2; Node node1 = new Node(8); Node node2 = new Node(4); Node node3 = new Node(5); Node node4 = new Node(3); Node node5 = new Node(9); Node node6 = new Node(2); node1.addChildNode(node2); node1.addChildNode(node3); node3.addChildNode(node4); node1.addChildNode(node5); node5.addChildNode(node6); BFSearcher sut = new BFSearcher(); Node node = sut.search(node1, TARGET_VALUE); Assertions.assertThat(node).isEqualTo(node6); }
  • 16. u AAA Pattern: u The Arrange section of AAA takes up over 80% of the code in our test, but we can still easily jump to Act sections by looking at the comments. u ”sut" naming makes the test target stand out. u Without AAA Pattern u We have to start reading the code from beginning. u Test target buried in the sea of mock objects.
  • 17. 1. A test should be self-contained. We want to understand the code fast. We don't want to jump around different methods to understand the test flow. u It is preferred that you do not follow the DRY (Don't Repeat Yourself) principle. Striving for code reuse will lead to tightly coupled and inflexible test, which discourages refactoring.
  • 18. ❌ Don’t do this // Do not do this. Code reader has to scroll // up and down to understand the whole test logic. @Test public void testXYZ(){ // 1. arrange setup1(); setup2(); doSomething(); Target sut = new Target(); // 2. act actualResult = sut.doSomething(); // 3. assert Asserts.assertThat(222, actualResult); } private void setup1(){ … } private void setup2(){ … } private void doSomething(){ … }