SlideShare a Scribd company logo
1 of 57
Download to read offline
Introduction to
Unit Testing
Swanky Hsiao
swanky.hsiao@gmail.com
I am Hsiao Yu-Cheng
Blockchain Believer / Java Enthusiast / Agile
Lover / Portrait Photographer / Growth Hacker
You can find me at
https://www.linkedin.com/in/swanky/ and
https://swanky.github.io/
Hello!
“
I get paid for code that works, not for tests,
so my philosophy is to test as little as
possible to reach a given level of confidence.
- Kent Beck
Ref: tdd - How deep are your unit tests? - Stack Overflow
肯特·貝克(英語:Kent Beck,1961年-),美國著名軟體工程師與作家,在軟體工程方面有很大的貢獻。他是Smalltalk軟體的開發者,
設計模式的先驅,測試驅動開發的支持者,也是極限編程的創始者之一。曾在Facebook工作(Jan 2011-Feb 2018)。
曾為Smalltalk寫作了SUnit單元測試架構,之後將這個架構移植到Java,寫作了JUnit。
Image from Amazon & Text from Wiki
為什麼要寫測試?
維持軟體品質
為持續整合、持續部署、持續交付做準備
為什麼要寫測試?
誰在乎軟體品質?
Image from <15 books that every programmer should buy>
https://medium.com/@gsari/15-books-that-every-programmer-should-buy-85525b509633
不要拖累隊友
“
敏捷+維持軟體品質
敏捷軟體開發宣言
藉著親自並協助他人進行軟體開發,
我們正致力於發掘更優良的軟體開發方法。
透過這樣的努力,我們已建立以下價 值觀:
個人與互動 重於 流程與工具
可用的軟體 重於 詳盡的文件
與客戶合作 重於 合約協商
 回應變化 重於 遵循計劃
也就是說,雖然右側項目有其價 值,
但我們更重視左側項目。
敏捷宣言背後的原則
我們遵守這些原則 :
我們最優先的任務,
是透過及早並持續地交付有價 值的軟體
來滿足客戶需求。
竭誠歡迎改變需求,甚至已處開發後期亦然。
敏捷流程掌控變更,以維護客 戶的競爭優勢。
經常交付可用的軟體,
頻率可以從數週到數個月,
以較短時間間隔為佳。
業務人員與開發者
必須在專案全程中天天一起工作。
以積極的個人來建構專案,
給予他們所需的環境與支援,
並信任他們可以完成工作。
面對面的溝通
是傳遞資訊給開發團隊及團隊成員之間
效率最高且效果最佳的方法。
可用的軟體是最主要的進度量測方法。
敏捷程序提倡可持續的開發。
贊助者、開發者及使用者應當能不斷地維持穩定的步調。
持續追求優越的技術與優良的設計,
以強化敏捷性。
精簡──或最大化未完成工作量之技藝 ──是不可或缺的。
最佳的架構、需求與設計皆來自於
能自我組織的團隊。
團隊定期自省如何更有效率,
並據之適當地調整與修正自己的行為。
“
持續交付是近年來軟體工程非常熱門的一個趨勢
它把敏捷的概念又括展到更廣的範圍,同時用全新的思維大幅
縮短軟體交付週期、減少浪費、提高品質
許多頂尖軟體公司靠這個方法,大幅提升速度,取得比競爭對
手快上數十倍的優勢,同時也獲得更高品質,使得不使用持續
交付的公司,即使有再好的創意,依然被使用持續交付的競爭
對手徹底擊敗。
Ref: 持續交付在Android專案中的實踐
http://jcconf.tw/2015/speaker/ci-android-project.html
早在2009年,Flickr就分享了他們如何通過工具
的支持和文化的改變,使之能 夠支撐業務部門
「每天部署10次」的要求。
“
為持續整合、持續部署、持續交付做準備
「持續整合」:儘快讓新功能的程式碼整合到現存的基礎程式庫(codebase) 中來進行測試
「持續部署」:讓軟體可以快速自動部署到不同的環境
「持續交付」:將新的特性儘快交付到最終使用者(end-user) 的手中
持續整合前置作業
1. 版本控制
2. 自動化建置
3. 團隊共識
持續整合前提條件
1. 頻繁簽入
2. 建立全面的自動化測試套件
3. 保持較短的建置和測試流程
Ref:
持續整合開發實踐術
http://www.ithome.com.tw/article/94710
山姆鍋對持續整合、持續部署、持續交付的定義
https://samkuo.me/post/2013/10/continuous-integration-deployment-delivery/
測試的種類 - 測試的階段
1. 單元測試:為最小單位的測試。在單元測試行為中,各獨立單元模組在與系統其他模組隔離的情
況下進行測試,檢查每個程式模組是否實現了規定的功能。
2. 整合測試:是在單元測試的基礎上將已經通過測試的單元模組按照設計要求組裝成系統或子系
統進行測試的活動。測試著重在各模組、各子系統之間介面上的缺陷。
3. 系統測試:透過整合測試的軟體,同其運作環境、資料和使用者結合在一起,在實際或模擬實際
環境下,對系統進行全面的測試。目的在於通過與系統需求規格書進行比較,發現軟體與系統
定義不符合的地方。(功能測試:檢查軟體的功能是否符合規格說明書上的需求。)
4. 驗收測試:為最後一個測試行為。它是以使用者為主的測試,由使用者設計測試案例,使用實際
資料進行測試。
Ref: 軟體測試專案實作-技術、流程與管理
Unit Test的特性: FIRST
◉ Fast
◉ Independent
◉ Repeatable
◉ Self-Validating
◉ Timely
From: <<Agile Testing: A Practical Guide for Testers and Agile Teams>>
Image from “Building Microservices” Ch.7
Brian Marick的測試象限
業務面向
支援編程
技術面向
評價產品
Ref:
TestPyramid
http://martinfowler.com/bliki/TestPyramid.html
Inverting the Testing Pyramid
http://blogs.agilefaqs.com/2011/02/01/inverting-the-testing-pyramid/
testing pyramid - 100,000 e2e selenium tests? Sounds like a nightmare!
http://watirmelon.com/tag/testing-pyramid/
Test Pyramid
From <<Succeeding with Agile: Software Development Using Scrum>>
Image from “Building Microservices” Ch.7, TestPyramid
Mike Cohn的測試金字塔
Image from “Building Microservices” Ch.7
酬賓方案系統
Unit Tests
Image from “Building Microservices” Ch.7
Service Tests
Image from “Building Microservices” Ch.7
End-to-End Tests
Image from “Building Microservices” Ch.7
Image from “Building Microservices” Ch.7
「working software based on working test cases」
Ref:
Unit Testing 簡介
https://ithelp.ithome.com.tw/articles/10102264
RoR之父批TDD已死,你認同嗎?
http://www.ithome.com.tw/news/87245
返璞歸真 -- 以最適當的方式設計軟體
http://blog.xdite.net/posts/2014/04/28/back-to-basic
關於BDD/TDD的三大誤解
http://teddy-chen-tw.blogspot.tw/2014/09/bddtdd.html
Unit Testing的價值被過度高估
http://kojenchieh.pixnet.net/blog/post/75407404
【單元測試】改變了我程式設計的思維方式
http://www.codedata.com.tw/java/unit-test-the-way-changes-my-program
ming
編寫單元測試不僅是一種驗證的行為,更是一種設計的行為,而且也是一種撰寫文件的行為。
撰寫單元測試的行為省去了相當多的反饋循環(feedback loop),最起碼節省了功能驗證方面的循環。
- 敏捷軟體開發:原則、樣式及實務(Agile Software Development: Principles, Patterns, and Practices)
測試碼可以簡省手動測試的時間,但有錯時無法告訴我們錯誤的源頭在那。
Unit test可以告訴我們錯誤的源頭在那,可是unit test 有時間成本和維護成本。寫過多unit test 反而有害。
TDD 藉由先寫測試避開unit test 的成本問題,並帶來其它好處。
-fcamel's blog
為何我們要學 Testing,是因為 Testing 可以帶給我們更 Solid 的程式。這在需要長久維護、或
者是需要多人協作、牽扯外部第三方元件的程式中至關重要。
你不應該被任何名詞綁架,而應該以這三點:「好讀、易維護、以全局觀點思考,為基準點」去
設計你的程式。
- xdite
UI 類的程式我現階段已放棄寫 Unit Test,不論是 web 還是 mobile。原因就是 UI 是 side effect,很難寫。可以硬寫,但是很難維護,
因為 UI 流程改動一下就要改很久,投資報酬率太低。這部份如果要自動化測試的話,通常是做 Functional Test,而不是 Unit Test。
不過 Functional Test 我們公司也是沒做自動化,只有人工測試。透過人工實際使用 app,測使用案例,也測 UI 有沒有異常。
沒有自動化測試,品質就比較難維持, bug 就會多,但如果開發者開始花精神維護 Functonal Test 測功能測 UI,那成本實在太傷,
整天都在維護那些難寫的測試,正事都不用做了。
沒自動化測試的程式,也沒專職的 QA 把關,我們公司的解法是靠 pair programming,這算是確保每一行程式,都是由兩位開發者
產生和驗證過的。我不是 說用 pair 就能取代 QA 和測試,只是 pair 對於降低 bug 出現率多少有點幫助。因為實行 pair,所以也省
下 code review 的時間。
- ingram
測試驅動開發
(TDD)
Test-Driven Development (TDD)
Test-Driven Development (TDD) is a computer programming
technique that involves repeatedly first writing a test case and then
implementing only the code necessary to pass the test.
◉ The goal of test-driven development is to achieve rapid feedback.
◉ The technique began to receive publicity in the early 2000s as an aspect of
Extreme Programming, but more recently is creating more general interest in its
own right.
The Rhythm of TDD
1. Quickly add a test.
2. Run all test and see the new one fail.
3. Make a little change.
Run all tests and see them all succeed.
4. Refactor to remove duplication.
Inner and outer feedback loops in TDD
Acceptance: Does the whole system work?
Integration: Does our code work against code we can't
change?
Unit: Do our objects do the right thing, are they convenient
to work with? Ref: Growing Object-Oriented Software, Guided by Tests
TDD + Refactoring
“
I'm not a great programmer; I'm just a
good programmer with great habits.
- Kent Beck in: Martin Fowler, Kent Beck, John Brant (2012) Refactoring: Improving the Design of Existing Code.
“
To write good tests
first we need to learn
how to program
- Alvaro Videla, Co-author of <<RabbitMQ in Action>>
Coupling and Cohesion
Coupling and cohesion are metrics that (roughly) describe how easy it will be to change the behavior of some code.
● Elements are coupled if a change in one forces a change in the other
○ For example, if two classes inherit from a common parent, then a change in one class might require a change in the
other. Think of a combo audio system: It's tightly coupled because if we want to change from analog to digital radio,
we must rebuild the whole system. If we assemble a system from separates, it would have low coupling and we
could just swap out the receiver. "Loosely" coupled features (i.e., those with low coupling) are easier to maintain.
● An element's cohesion is a measure of whether its responsibilities form a meaningful unit
○ For example, a class that parses both dates and URLs is not coherent, because they're unrelated concepts. Think of a
machine that washes both clothes and dishes—it's unlikely to do both well. At the other extreme, a class that parses
only the punctuation in a URL is unlikely to be coherent, because it doesn't represent a whole concept. To get anything
done, the programmer will have to find other parsers for protocol, host, resource, and so on. Features with "high"
coherence are easier to maintain.
SOLID Principles
Single Responsibility Principle
(SRP)
A class should have only one
reason to change.
Open Closed Principle (OCP)
Software entities (classes,
modules, functions, etc.) should
be open for extension, but
closed for modification.
Liskov Substitution Principle
(LSP)
Objects in a program should be
replaceable with instances of
their subtypes without altering
the correctness of that program.
Interface Segregation Principle
(ISP)
Many client-specific interfaces
are better than one
general-purpose interface.
Dependency Inversion Principle
(DIP)
High-level modules should not
depend on low-level modules.
Both should depend on
abstractions.
Abstractions should not depend
on details. Details should
depend on abstractions.
Ref: SOLID Principles : The Definitive Guide
https://android.jlelse.eu/solid-principles-the-d
efinitive-guide-75e30a284dea
如何進行?
◉ 熟悉測試相關API, Mock工具, IDE環境
JUnit, Spring MVC Test Framework, AssertJ, Mockito, ...
◉ 學習測試相關技術:Testing、Refactoring、TDD、ATDD & BDD
○ Test First可以確保測試的高涵蓋率,因為總是先有測試的程式,才有實際的成品
○ Test First可以確保API的設計完善,因為你是先從 API使用者角度的開始延伸
○ Test First可以確保程式高模組化,因為如果不先規畫好模組,測試很難進行
Ref:
Testing modern web applications
http://g00glen00b.be/testing-modern-web-applications/
Spring MVC Test Tutorial
http://www.petrikainulainen.net/spring-mvc-test-tutorial/
Test Driven Development 經驗整理
https://ingramchen.io/blog/2014/04/how-i-do-test-driven-development.html
xUnit
Automating Tests
List fixture = new ArrayList();
// fixture should be empty
Object element = new Object();
fixture.add(element);
// fixture should have one element
Ref: JUnit Pocket Guide
Automating Tests
Step 1: Just Print It!
List fixture = new ArrayList();
System.out.println(fixture.size());
Object element = new Object();
fixture.add(element);
System.out.println(fixture.size());
Ref: JUnit Pocket Guide
Automating Tests
Step 2: Print with boolean expr
List fixture = new ArrayList();
System.out.println(fixture.size() == 0);
Object element = new Object();
fixture.add(element);
System.out.println(fixture.size() == 1);
Ref: JUnit Pocket Guide
Automating Tests
Step 3: Test with assertion method
void assertTrue(boolean condition) throws Exception {
if(!condition)
throw new Exception("Assertion failed");
}
List fixture = new ArrayList();
assertTrue(fixture.size() == 0);
Object element = new Object();
fixture.add(element);
assertTrue(fixture.size() == 1);
Ref: JUnit Pocket Guide
JUnit
JUnit is a regression testing framework written by Erich Gamma and Kent Beck.
In 1997, Erich Gamma and Kent Beck created a simple but effective unit testing framework for Java, called JUnit.
Framework – A framework is a semi-complete application. A framework provides a reusable, common structure that
can be shared between applications. Developers incorporate the framework into their own application and extend it to
meet their specific needs. Frameworks differ from toolkits by providing a coherent structure, rather than a simple set of
utility classes.
Erich Gamma is well known as one of the “Gang of Four” who gave us the now classic Design Patterns book.
Kent Beck is equally well known for his groundbreaking work in the software discipline known as Extreme Programming.
Regression testing is any type of software testing which seeks to uncover regression bugs. Regression bugs occur
whenever software functionality that previously worked as desired stops working or no longer works in the same way
that was previously planned. Typically regression bugs occur as an unintended consequence of program changes.
JUnit is a framework that automates the tedious,
repetitive parts of writing tests
◉ Runs tests automatically
◉ Runs many tests together and summarizes the results
◉ Provides a convenient place to collect the tests you’ve written
◉ Provides a convenient place for sharing the code used to
create the objects you are going to test
◉ Compares actual results to expected results and reports
differences
“
When I write automated tests I feel more confident
in my work than when I don’t write automated tests.
When I program test-first I can have confidence
throughout the process, Tests give me confidence that
I know what problem I’m trying to solve.
- Kent Beck
JUnit Annotations
Annotation Description
@Test
public void method()
The @Test annotation identifies a method as a test method.
@Test(expected = Exception.class) Fails if the method does not throw the named exception.
@Test(timeout = 100) Fails if the method takes longer than 100 milliseconds.
@Before
public void method()
This method is executed before each test. It is used to prepare the test environment (e.g., read input data, initialize the class).
@After
public void method()
This method is executed after each test. It is used to cleanup the test environment (e.g., delete temporary data, restore
defaults). It can also save memory by cleaning up expensive memory structures.
@BeforeClass
public static void method()
This method is executed once, before the start of all tests. It is used to perform time intensive activities, for example, to
connect to a database. Methods marked with this annotation need to be defined as static to work with JUnit.
@AfterClass
public static void method()
This method is executed once, after all tests have been finished. It is used to perform clean-up activities, for example, to
disconnect from a database. Methods annotated with this annotation need to be defined as static to work with JUnit.
@Ignore or
@Ignore("Why disabled")
Ignores the test method. This is useful when the underlying code has been changed and the test case has not yet been
adapted. Or if the execution time of this test is too long to be included. It is best practice to provide the optional description,
why the test is disabled.
JUnit Assert Statements
Statement Description
fail(message)
Let the method fail. Might be used to check that a certain part of the code is not reached or to
have a failing test before the test code is implemented. The message parameter is optional.
assertTrue([message,] boolean condition) Checks that the boolean condition is true.
assertFalse([message,] boolean condition) Checks that the boolean condition is false.
assertEquals([message,] expected, actual)
Tests that two values are the same. Note: for arrays the reference is checked not the content
of arrays.
assertEquals([message,] expected, actual,
tolerance)
Test that float or double values match. The tolerance is the number of decimals which must
be the same.
assertNull([message,] object) Checks that the objects is null.
assertNotNull([message,] object) Checks that the objects is not null.
assertSame([message,] expected, actual) Checks that both variables refer to the same object.
assertNotSame([message,] expected, actual) Checks that both variables refer to different objects.
Creating Tests with
IntelliJ
◉ Use the intention action
○ Place the cursor on the class name
○ Press Alt+Enter
◉ Use Navigation
○ On the main menu, choose Navigate | Test
○ On the context menu, choose Go to | Test
Creating Tests with
Eclipse + MoreUnit
Ref: Walkthrough for a TDD Kata in Eclipse
https://advancedweb.hu/2015/10/27/eclipse_tdd/
“
Bowling Game Kata
Ref: TheBowlingGameKata
http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
AssertJ
ThoughtWorks Technology Radar - TRIAL (NOV 2017)
AssertJ is a Java library that provides a fluent interface for assertions, which makes it
easy to convey intent within test code. AssertJ gives readable error messages, soft
assertions, and improved collections and exception support. We're seeing some
teams default to its use instead of JUnit combined with Hamcrest.
NORMAL
private void makeNormal(Customer customer) {
Order o1 = new Order();
customer.addOrder(o1);
OrderLine line1 = new OrderLine(6, Product.find("TAL"));
o1.addLine(line1);
OrderLine line2 = new OrderLine(5, Product.find("HPK"));
o1.addLine(line2);
OrderLine line3 = new OrderLine(3, Product.find("LGV"));
o1.addLine(line3);
line2.setSkippable(true);
o1.setRush(true);
}
FLUENT
private void makeFluent(Customer customer) {
customer.newOrder()
.with(6, "TAL")
.with(5, "HPK").skippable()
.with(3, "LGV")
.priorityRush();
}
// entry point for all assertThat methods and utility methods (e.g. entry)
import static org.assertj.core.api.Assertions.*;
// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);
// chaining string specific assertions
assertThat(frodo.getName()).startsWith("Fro")
.endsWith("do")
.isEqualToIgnoringCase("frodo");
// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
.contains(frodo, sam)
.doesNotContain(sauron);
// as() is used to describe the test and will be shown before the error message
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);
// Java 8 exception assertion, standard style ...
assertThatThrownBy(() -> { throw new Exception("boom!"); }).hasMessage("boom!");
// ... or BDD style
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
assertThat(thrown).hasMessageContaining("boom");
// using the 'extracting' feature to check fellowshipOfTheRing character's names (Java 7)
assertThat(fellowshipOfTheRing).extracting("name")
.contains("Boromir", "Gandalf", "Frodo", "Legolas")
// same thing using a Java 8 method reference
assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getName)
.doesNotContain("Sauron", "Elrond");
// extracting multiple values at once grouped in tuples (Java 7)
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
.contains(tuple("Boromir", 37, "Man"),
tuple("Sam", 38, "Hobbit"),
tuple("Legolas", 1000, "Elf"));
// filtering a collection before asserting in Java 7 ...
assertThat(fellowshipOfTheRing).filteredOn("race", HOBBIT)
.containsOnly(sam, frodo, pippin, merry);
// ... or in Java 8
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
.containsOnly(aragorn, frodo, legolas, boromir);
// combining filtering and extraction (yes we can)
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
.containsOnly(aragorn, frodo, legolas, boromir)
.extracting(character -> character.getRace().getName())
.contains("Hobbit", "Elf", "Man");
// and many more assertions: iterable, stream, array, map, dates (java 7 and 8), path,
file, numbers, predicate, optional ...
MOCKERY
Test Double
Test Double
Test Double is a generic term for
any case where you replace a
production object for testing
purpose. There are various kinds
of double list : Dummy、Fake、
Stub、Mock and Spy.
Dummy
Objects are passed around but
never actually used. Usually they
are just used to fill parameter
lists.
Fake
Objects actually have working
implementations, but usually
take some shortcut which makes
them not suitable for
production.
Stub
Stub provide canned answers to
calls made during the test.
Mock
Mocks are pre-programmed
with expectations which form a
specification of the calls they are
expected to receive.
Spy
Spies are stubs that also record
some information based on how
they were called.
Ref: Martin Fowler - TestDouble
https://martinfowler.com/bliki/TestDouble.html
Mockito
Mockito is a mocking framework for unit tests in Java. It has been designed to be
intuitive to use when the test needs mocks.
Verify interactions
import static org.mockito.Mockito.*;
// mock creation
List mockedList = mock(List.class);
// using mock object - it does not throw any
"unexpected interaction" exception
mockedList.add("one");
mockedList.clear();
// selective, explicit, highly readable verification
verify(mockedList).add("one");
verify(mockedList).clear();
Stub method calls
// you can mock concrete classes, not only interfaces
LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");
// the following prints "first"
System.out.println(mockedList.get(0));
// the following prints "null" because get(999) was
not stubbed
System.out.println(mockedList.get(999));
List<String> mockedList = mock(List. class);
//using mock
mockedList.add("once");
mockedList.add("twice");
mockedList.add("twice" );
mockedList.add("three times");
mockedList.add("three times");
mockedList.add("three times");
/**
* 基本的驗證方法
* verify方法驗證mock對像是否有沒有調用mockedList.add("once")方法
* 不關心其是否有返回值,如果沒有調用測試失敗。
*/
verify(mockedList).add("once");
//默認調用一次,times(1)可以省略
verify(mockedList, times(1)).add("once");
verify(mockedList, times(2)).add("twice");
verify(mockedList, times(3)).add("three times");
//never()等同於time(0),一次也沒有調用
verify(mockedList, times(0)).add("never happened");
//atLeastOnece/atLeast()/atMost()
verify(mockedList, atLeastOnce()).add("three times");
verify(mockedList, atLeast(2)).add("twice");
verify(mockedList, atMost(5)).add("three times");
參數匹配器
//stubbing using built-in anyInt() argument matcher
when(mockedList.get(anyInt())).thenReturn("element");
//stubbing using custom matcher (let's say isValid()
returns your own matcher implementation):
when(mockedList.contains(argThat(isValid()))).thenReturn(
"element");
//following prints "element"
System.out.println(mockedList.get(999));
//you can also verify using an argument matcher
verify(mockedList).get(anyInt());
“
Inside every well-written large
program is a well-written small
program.
- Charles Antony Richard Hoare, computer scientist
Reference
◉ Effective Tests
https://lostechies.com/derekgreer/2011/03/07/effective-tests-introduction/
◉ 30天快速上手TDD
https://dotblogs.com.tw/hatelove/2013/01/11/learning-tdd-in-30-days-catalog-and-reference
◉ Coding Dojo
http://www.codingdojo.org/KataCatalogue/
◉ 五分钟让你彻底了解TDD、ATDD、BDD&RBE
https://mp.weixin.qq.com/s?__biz=MjM5ODczMDc1Mw==&mid=2651844175&idx=1&sn=c6b17d9dc7ab0f4169e91
49df33d0fb6
Any questions ?
You can find me at
◉ swanky.hsiao@gmail.com
Thanks!

More Related Content

What's hot

A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD) A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD) CodeOps Technologies LLP
 
Test-Driven Development
Test-Driven DevelopmentTest-Driven Development
Test-Driven DevelopmentJohn Blum
 
Testing on Android
Testing on AndroidTesting on Android
Testing on AndroidAri Lacenski
 
Design for testability as a way to good coding (SOLID and IoC)
Design for testability as a way to good coding (SOLID and IoC)Design for testability as a way to good coding (SOLID and IoC)
Design for testability as a way to good coding (SOLID and IoC)Simone Chiaretta
 
The Open-Closed Principle - the Original Version and the Contemporary Version
The Open-Closed Principle - the Original Version and the Contemporary VersionThe Open-Closed Principle - the Original Version and the Contemporary Version
The Open-Closed Principle - the Original Version and the Contemporary VersionPhilip Schwarz
 
Beyond Testing: Specs and Behavior Driven Development
Beyond Testing: Specs and Behavior  Driven DevelopmentBeyond Testing: Specs and Behavior  Driven Development
Beyond Testing: Specs and Behavior Driven DevelopmentRabble .
 
Object Oriented Design SOLID Principles
Object Oriented Design SOLID PrinciplesObject Oriented Design SOLID Principles
Object Oriented Design SOLID Principlesrainynovember12
 
The Open Closed Principle - Part 1 - The Original Version
The Open Closed Principle - Part 1 - The Original VersionThe Open Closed Principle - Part 1 - The Original Version
The Open Closed Principle - Part 1 - The Original VersionPhilip Schwarz
 
Test Driven Development (TDD)
Test Driven Development (TDD)Test Driven Development (TDD)
Test Driven Development (TDD)David Ehringer
 
Agile Programming Systems # TDD intro
Agile Programming Systems # TDD introAgile Programming Systems # TDD intro
Agile Programming Systems # TDD introVitaliy Kulikov
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven DevelopmentTung Nguyen Thanh
 
Open Close Principle
Open Close PrincipleOpen Close Principle
Open Close PrincipleThaichor Seng
 
How we tested our code "Google way"
How we tested our code "Google way"How we tested our code "Google way"
How we tested our code "Google way"Oleksiy Rezchykov
 
Test driven development
Test driven developmentTest driven development
Test driven developmentNascenia IT
 
Being a professional software tester
Being a professional software testerBeing a professional software tester
Being a professional software testerAnton Keks
 
The OO Design Principles
The OO Design PrinciplesThe OO Design Principles
The OO Design PrinciplesSteve Zhang
 
Object Oriented Design Principles
Object Oriented Design PrinciplesObject Oriented Design Principles
Object Oriented Design PrinciplesThang Tran Duc
 

What's hot (20)

Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD) A Not-So-Serious Introduction to Test Driven Development (TDD)
A Not-So-Serious Introduction to Test Driven Development (TDD)
 
Test-Driven Development
Test-Driven DevelopmentTest-Driven Development
Test-Driven Development
 
Driven to Tests
Driven to TestsDriven to Tests
Driven to Tests
 
Testing on Android
Testing on AndroidTesting on Android
Testing on Android
 
Design for testability as a way to good coding (SOLID and IoC)
Design for testability as a way to good coding (SOLID and IoC)Design for testability as a way to good coding (SOLID and IoC)
Design for testability as a way to good coding (SOLID and IoC)
 
The Open-Closed Principle - the Original Version and the Contemporary Version
The Open-Closed Principle - the Original Version and the Contemporary VersionThe Open-Closed Principle - the Original Version and the Contemporary Version
The Open-Closed Principle - the Original Version and the Contemporary Version
 
Beyond Testing: Specs and Behavior Driven Development
Beyond Testing: Specs and Behavior  Driven DevelopmentBeyond Testing: Specs and Behavior  Driven Development
Beyond Testing: Specs and Behavior Driven Development
 
Object Oriented Design SOLID Principles
Object Oriented Design SOLID PrinciplesObject Oriented Design SOLID Principles
Object Oriented Design SOLID Principles
 
The Open Closed Principle - Part 1 - The Original Version
The Open Closed Principle - Part 1 - The Original VersionThe Open Closed Principle - Part 1 - The Original Version
The Open Closed Principle - Part 1 - The Original Version
 
Test Driven Development (TDD)
Test Driven Development (TDD)Test Driven Development (TDD)
Test Driven Development (TDD)
 
Agile Programming Systems # TDD intro
Agile Programming Systems # TDD introAgile Programming Systems # TDD intro
Agile Programming Systems # TDD intro
 
TDD - Test Driven Development
TDD - Test Driven DevelopmentTDD - Test Driven Development
TDD - Test Driven Development
 
Open Close Principle
Open Close PrincipleOpen Close Principle
Open Close Principle
 
How we tested our code "Google way"
How we tested our code "Google way"How we tested our code "Google way"
How we tested our code "Google way"
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Being a professional software tester
Being a professional software testerBeing a professional software tester
Being a professional software tester
 
Simple is the best
Simple is the bestSimple is the best
Simple is the best
 
The OO Design Principles
The OO Design PrinciplesThe OO Design Principles
The OO Design Principles
 
Object Oriented Design Principles
Object Oriented Design PrinciplesObject Oriented Design Principles
Object Oriented Design Principles
 

Similar to Introduction to Unit Testing

Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...Applitools
 
Growing Object Oriented Software
Growing Object Oriented SoftwareGrowing Object Oriented Software
Growing Object Oriented SoftwareAnnmarie Lanesey
 
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Abdelkrim Boujraf
 
DevOps - Boldly Go for Distro
DevOps - Boldly Go for DistroDevOps - Boldly Go for Distro
DevOps - Boldly Go for DistroPaul Boos
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@Alex Borsuk
 
Unit Testing Fundamentals
Unit Testing FundamentalsUnit Testing Fundamentals
Unit Testing FundamentalsRichard Paul
 
Selenium - The Way Of Success
Selenium - The Way Of SuccessSelenium - The Way Of Success
Selenium - The Way Of SuccessZbyszek Mockun
 
Open Source tools in Continuous Integration environment (case study for agil...
Open Source tools in Continuous Integration environment  (case study for agil...Open Source tools in Continuous Integration environment  (case study for agil...
Open Source tools in Continuous Integration environment (case study for agil...suwalki24.pl
 
Continuous Integration testing based on Selenium and Hudson
Continuous Integration testing based on Selenium and HudsonContinuous Integration testing based on Selenium and Hudson
Continuous Integration testing based on Selenium and HudsonZbyszek Mockun
 
Agile Engineering
Agile EngineeringAgile Engineering
Agile EngineeringJohn Lewis
 
Test Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, MockingTest Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, Mockingmrjawright
 
Adm Initial Proposal
Adm Initial ProposalAdm Initial Proposal
Adm Initial Proposalcfry
 
SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionKnoldus Inc.
 
Devops - Continuous Integration And Continuous Development
Devops - Continuous Integration And Continuous DevelopmentDevops - Continuous Integration And Continuous Development
Devops - Continuous Integration And Continuous DevelopmentSandyJohn5
 
The Design, Evolution and Use of KernelF
The Design, Evolution and Use of KernelFThe Design, Evolution and Use of KernelF
The Design, Evolution and Use of KernelFMarkus Voelter
 
Bulletproof design systems using storybook
Bulletproof design systems using storybookBulletproof design systems using storybook
Bulletproof design systems using storybookChen Feldman
 
Accelerate your Application Delivery with DevOps and Microservices
Accelerate your Application Delivery with DevOps and MicroservicesAccelerate your Application Delivery with DevOps and Microservices
Accelerate your Application Delivery with DevOps and MicroservicesAmazon Web Services
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Hong Le Van
 

Similar to Introduction to Unit Testing (20)

TDD Workshop UTN 2012
TDD Workshop UTN 2012TDD Workshop UTN 2012
TDD Workshop UTN 2012
 
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
Testing Hourglass at Jira Frontend - by Alexey Shpakov, Sr. Developer @ Atlas...
 
Growing Object Oriented Software
Growing Object Oriented SoftwareGrowing Object Oriented Software
Growing Object Oriented Software
 
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
 
DevOps - Boldly Go for Distro
DevOps - Boldly Go for DistroDevOps - Boldly Go for Distro
DevOps - Boldly Go for Distro
 
Unit Testing Full@
Unit Testing Full@Unit Testing Full@
Unit Testing Full@
 
Unit Testing Fundamentals
Unit Testing FundamentalsUnit Testing Fundamentals
Unit Testing Fundamentals
 
Selenium - The Way Of Success
Selenium - The Way Of SuccessSelenium - The Way Of Success
Selenium - The Way Of Success
 
Open Source tools in Continuous Integration environment (case study for agil...
Open Source tools in Continuous Integration environment  (case study for agil...Open Source tools in Continuous Integration environment  (case study for agil...
Open Source tools in Continuous Integration environment (case study for agil...
 
Continuous Integration testing based on Selenium and Hudson
Continuous Integration testing based on Selenium and HudsonContinuous Integration testing based on Selenium and Hudson
Continuous Integration testing based on Selenium and Hudson
 
Agile Engineering
Agile EngineeringAgile Engineering
Agile Engineering
 
Test Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, MockingTest Driven Development:Unit Testing, Dependency Injection, Mocking
Test Driven Development:Unit Testing, Dependency Injection, Mocking
 
Adm Initial Proposal
Adm Initial ProposalAdm Initial Proposal
Adm Initial Proposal
 
SOLID Design Principles for Test Automaion
SOLID Design Principles for Test AutomaionSOLID Design Principles for Test Automaion
SOLID Design Principles for Test Automaion
 
Devops - Continuous Integration And Continuous Development
Devops - Continuous Integration And Continuous DevelopmentDevops - Continuous Integration And Continuous Development
Devops - Continuous Integration And Continuous Development
 
Why test with flex unit
Why test with flex unitWhy test with flex unit
Why test with flex unit
 
The Design, Evolution and Use of KernelF
The Design, Evolution and Use of KernelFThe Design, Evolution and Use of KernelF
The Design, Evolution and Use of KernelF
 
Bulletproof design systems using storybook
Bulletproof design systems using storybookBulletproof design systems using storybook
Bulletproof design systems using storybook
 
Accelerate your Application Delivery with DevOps and Microservices
Accelerate your Application Delivery with DevOps and MicroservicesAccelerate your Application Delivery with DevOps and Microservices
Accelerate your Application Delivery with DevOps and Microservices
 
Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++Test driven development and unit testing with examples in C++
Test driven development and unit testing with examples in C++
 

Recently uploaded

“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...
“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...
“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...Marc Dusseiller Dusjagr
 
Introduction to AI in Higher Education_draft.pptx
Introduction to AI in Higher Education_draft.pptxIntroduction to AI in Higher Education_draft.pptx
Introduction to AI in Higher Education_draft.pptxpboyjonauth
 
Organic Name Reactions for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions  for the students and aspirants of Chemistry12th.pptxOrganic Name Reactions  for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions for the students and aspirants of Chemistry12th.pptxVS Mahajan Coaching Centre
 
CARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptxCARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptxGaneshChakor2
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactPECB
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Sapana Sha
 
A Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformA Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformChameera Dedduwage
 
Separation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and ActinidesSeparation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and ActinidesFatimaKhan178732
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdfQucHHunhnh
 
Employee wellbeing at the workplace.pptx
Employee wellbeing at the workplace.pptxEmployee wellbeing at the workplace.pptx
Employee wellbeing at the workplace.pptxNirmalaLoungPoorunde1
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Celine George
 
Mastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory InspectionMastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory InspectionSafetyChain Software
 
Accessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactAccessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactdawncurless
 
URLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website AppURLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website AppCeline George
 
Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfJayanti Pande
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxSayali Powar
 

Recently uploaded (20)

Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
Mattingly "AI & Prompt Design: Structured Data, Assistants, & RAG"
 
“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...
“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...
“Oh GOSH! Reflecting on Hackteria's Collaborative Practices in a Global Do-It...
 
Introduction to AI in Higher Education_draft.pptx
Introduction to AI in Higher Education_draft.pptxIntroduction to AI in Higher Education_draft.pptx
Introduction to AI in Higher Education_draft.pptx
 
Organic Name Reactions for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions  for the students and aspirants of Chemistry12th.pptxOrganic Name Reactions  for the students and aspirants of Chemistry12th.pptx
Organic Name Reactions for the students and aspirants of Chemistry12th.pptx
 
CARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptxCARE OF CHILD IN INCUBATOR..........pptx
CARE OF CHILD IN INCUBATOR..........pptx
 
Beyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global ImpactBeyond the EU: DORA and NIS 2 Directive's Global Impact
Beyond the EU: DORA and NIS 2 Directive's Global Impact
 
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111Call Girls in Dwarka Mor Delhi Contact Us 9654467111
Call Girls in Dwarka Mor Delhi Contact Us 9654467111
 
A Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy ReformA Critique of the Proposed National Education Policy Reform
A Critique of the Proposed National Education Policy Reform
 
Separation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and ActinidesSeparation of Lanthanides/ Lanthanides and Actinides
Separation of Lanthanides/ Lanthanides and Actinides
 
1029-Danh muc Sach Giao Khoa khoi 6.pdf
1029-Danh muc Sach Giao Khoa khoi  6.pdf1029-Danh muc Sach Giao Khoa khoi  6.pdf
1029-Danh muc Sach Giao Khoa khoi 6.pdf
 
Employee wellbeing at the workplace.pptx
Employee wellbeing at the workplace.pptxEmployee wellbeing at the workplace.pptx
Employee wellbeing at the workplace.pptx
 
Mattingly "AI & Prompt Design: The Basics of Prompt Design"
Mattingly "AI & Prompt Design: The Basics of Prompt Design"Mattingly "AI & Prompt Design: The Basics of Prompt Design"
Mattingly "AI & Prompt Design: The Basics of Prompt Design"
 
Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17Advanced Views - Calendar View in Odoo 17
Advanced Views - Calendar View in Odoo 17
 
Mastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory InspectionMastering the Unannounced Regulatory Inspection
Mastering the Unannounced Regulatory Inspection
 
Accessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impactAccessible design: Minimum effort, maximum impact
Accessible design: Minimum effort, maximum impact
 
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdfTataKelola dan KamSiber Kecerdasan Buatan v022.pdf
TataKelola dan KamSiber Kecerdasan Buatan v022.pdf
 
URLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website AppURLs and Routing in the Odoo 17 Website App
URLs and Routing in the Odoo 17 Website App
 
Web & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdfWeb & Social Media Analytics Previous Year Question Paper.pdf
Web & Social Media Analytics Previous Year Question Paper.pdf
 
Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1Código Creativo y Arte de Software | Unidad 1
Código Creativo y Arte de Software | Unidad 1
 
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptxPOINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
POINT- BIOCHEMISTRY SEM 2 ENZYMES UNIT 5.pptx
 

Introduction to Unit Testing

  • 1. Introduction to Unit Testing Swanky Hsiao swanky.hsiao@gmail.com
  • 2. I am Hsiao Yu-Cheng Blockchain Believer / Java Enthusiast / Agile Lover / Portrait Photographer / Growth Hacker You can find me at https://www.linkedin.com/in/swanky/ and https://swanky.github.io/ Hello!
  • 3. “ I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence. - Kent Beck Ref: tdd - How deep are your unit tests? - Stack Overflow
  • 7. 誰在乎軟體品質? Image from <15 books that every programmer should buy> https://medium.com/@gsari/15-books-that-every-programmer-should-buy-85525b509633
  • 9. “ 敏捷+維持軟體品質 敏捷軟體開發宣言 藉著親自並協助他人進行軟體開發, 我們正致力於發掘更優良的軟體開發方法。 透過這樣的努力,我們已建立以下價 值觀: 個人與互動 重於 流程與工具 可用的軟體 重於 詳盡的文件 與客戶合作 重於 合約協商  回應變化 重於 遵循計劃 也就是說,雖然右側項目有其價 值, 但我們更重視左側項目。 敏捷宣言背後的原則 我們遵守這些原則 : 我們最優先的任務, 是透過及早並持續地交付有價 值的軟體 來滿足客戶需求。 竭誠歡迎改變需求,甚至已處開發後期亦然。 敏捷流程掌控變更,以維護客 戶的競爭優勢。 經常交付可用的軟體, 頻率可以從數週到數個月, 以較短時間間隔為佳。 業務人員與開發者 必須在專案全程中天天一起工作。 以積極的個人來建構專案, 給予他們所需的環境與支援, 並信任他們可以完成工作。 面對面的溝通 是傳遞資訊給開發團隊及團隊成員之間 效率最高且效果最佳的方法。 可用的軟體是最主要的進度量測方法。 敏捷程序提倡可持續的開發。 贊助者、開發者及使用者應當能不斷地維持穩定的步調。 持續追求優越的技術與優良的設計, 以強化敏捷性。 精簡──或最大化未完成工作量之技藝 ──是不可或缺的。 最佳的架構、需求與設計皆來自於 能自我組織的團隊。 團隊定期自省如何更有效率, 並據之適當地調整與修正自己的行為。
  • 11. “ 為持續整合、持續部署、持續交付做準備 「持續整合」:儘快讓新功能的程式碼整合到現存的基礎程式庫(codebase) 中來進行測試 「持續部署」:讓軟體可以快速自動部署到不同的環境 「持續交付」:將新的特性儘快交付到最終使用者(end-user) 的手中 持續整合前置作業 1. 版本控制 2. 自動化建置 3. 團隊共識 持續整合前提條件 1. 頻繁簽入 2. 建立全面的自動化測試套件 3. 保持較短的建置和測試流程 Ref: 持續整合開發實踐術 http://www.ithome.com.tw/article/94710 山姆鍋對持續整合、持續部署、持續交付的定義 https://samkuo.me/post/2013/10/continuous-integration-deployment-delivery/
  • 12.
  • 13. 測試的種類 - 測試的階段 1. 單元測試:為最小單位的測試。在單元測試行為中,各獨立單元模組在與系統其他模組隔離的情 況下進行測試,檢查每個程式模組是否實現了規定的功能。 2. 整合測試:是在單元測試的基礎上將已經通過測試的單元模組按照設計要求組裝成系統或子系 統進行測試的活動。測試著重在各模組、各子系統之間介面上的缺陷。 3. 系統測試:透過整合測試的軟體,同其運作環境、資料和使用者結合在一起,在實際或模擬實際 環境下,對系統進行全面的測試。目的在於通過與系統需求規格書進行比較,發現軟體與系統 定義不符合的地方。(功能測試:檢查軟體的功能是否符合規格說明書上的需求。) 4. 驗收測試:為最後一個測試行為。它是以使用者為主的測試,由使用者設計測試案例,使用實際 資料進行測試。 Ref: 軟體測試專案實作-技術、流程與管理
  • 14. Unit Test的特性: FIRST ◉ Fast ◉ Independent ◉ Repeatable ◉ Self-Validating ◉ Timely
  • 15. From: <<Agile Testing: A Practical Guide for Testers and Agile Teams>> Image from “Building Microservices” Ch.7 Brian Marick的測試象限 業務面向 支援編程 技術面向 評價產品
  • 16. Ref: TestPyramid http://martinfowler.com/bliki/TestPyramid.html Inverting the Testing Pyramid http://blogs.agilefaqs.com/2011/02/01/inverting-the-testing-pyramid/ testing pyramid - 100,000 e2e selenium tests? Sounds like a nightmare! http://watirmelon.com/tag/testing-pyramid/ Test Pyramid
  • 17. From <<Succeeding with Agile: Software Development Using Scrum>> Image from “Building Microservices” Ch.7, TestPyramid Mike Cohn的測試金字塔
  • 18. Image from “Building Microservices” Ch.7 酬賓方案系統
  • 19. Unit Tests Image from “Building Microservices” Ch.7
  • 20. Service Tests Image from “Building Microservices” Ch.7
  • 21. End-to-End Tests Image from “Building Microservices” Ch.7
  • 22. Image from “Building Microservices” Ch.7
  • 23. 「working software based on working test cases」 Ref: Unit Testing 簡介 https://ithelp.ithome.com.tw/articles/10102264 RoR之父批TDD已死,你認同嗎? http://www.ithome.com.tw/news/87245 返璞歸真 -- 以最適當的方式設計軟體 http://blog.xdite.net/posts/2014/04/28/back-to-basic 關於BDD/TDD的三大誤解 http://teddy-chen-tw.blogspot.tw/2014/09/bddtdd.html Unit Testing的價值被過度高估 http://kojenchieh.pixnet.net/blog/post/75407404 【單元測試】改變了我程式設計的思維方式 http://www.codedata.com.tw/java/unit-test-the-way-changes-my-program ming 編寫單元測試不僅是一種驗證的行為,更是一種設計的行為,而且也是一種撰寫文件的行為。 撰寫單元測試的行為省去了相當多的反饋循環(feedback loop),最起碼節省了功能驗證方面的循環。 - 敏捷軟體開發:原則、樣式及實務(Agile Software Development: Principles, Patterns, and Practices) 測試碼可以簡省手動測試的時間,但有錯時無法告訴我們錯誤的源頭在那。 Unit test可以告訴我們錯誤的源頭在那,可是unit test 有時間成本和維護成本。寫過多unit test 反而有害。 TDD 藉由先寫測試避開unit test 的成本問題,並帶來其它好處。 -fcamel's blog 為何我們要學 Testing,是因為 Testing 可以帶給我們更 Solid 的程式。這在需要長久維護、或 者是需要多人協作、牽扯外部第三方元件的程式中至關重要。 你不應該被任何名詞綁架,而應該以這三點:「好讀、易維護、以全局觀點思考,為基準點」去 設計你的程式。 - xdite UI 類的程式我現階段已放棄寫 Unit Test,不論是 web 還是 mobile。原因就是 UI 是 side effect,很難寫。可以硬寫,但是很難維護, 因為 UI 流程改動一下就要改很久,投資報酬率太低。這部份如果要自動化測試的話,通常是做 Functional Test,而不是 Unit Test。 不過 Functional Test 我們公司也是沒做自動化,只有人工測試。透過人工實際使用 app,測使用案例,也測 UI 有沒有異常。 沒有自動化測試,品質就比較難維持, bug 就會多,但如果開發者開始花精神維護 Functonal Test 測功能測 UI,那成本實在太傷, 整天都在維護那些難寫的測試,正事都不用做了。 沒自動化測試的程式,也沒專職的 QA 把關,我們公司的解法是靠 pair programming,這算是確保每一行程式,都是由兩位開發者 產生和驗證過的。我不是 說用 pair 就能取代 QA 和測試,只是 pair 對於降低 bug 出現率多少有點幫助。因為實行 pair,所以也省 下 code review 的時間。 - ingram
  • 25. Test-Driven Development (TDD) Test-Driven Development (TDD) is a computer programming technique that involves repeatedly first writing a test case and then implementing only the code necessary to pass the test. ◉ The goal of test-driven development is to achieve rapid feedback. ◉ The technique began to receive publicity in the early 2000s as an aspect of Extreme Programming, but more recently is creating more general interest in its own right.
  • 26. The Rhythm of TDD 1. Quickly add a test. 2. Run all test and see the new one fail. 3. Make a little change. Run all tests and see them all succeed. 4. Refactor to remove duplication.
  • 27. Inner and outer feedback loops in TDD Acceptance: Does the whole system work? Integration: Does our code work against code we can't change? Unit: Do our objects do the right thing, are they convenient to work with? Ref: Growing Object-Oriented Software, Guided by Tests
  • 29. “ I'm not a great programmer; I'm just a good programmer with great habits. - Kent Beck in: Martin Fowler, Kent Beck, John Brant (2012) Refactoring: Improving the Design of Existing Code.
  • 30. “ To write good tests first we need to learn how to program - Alvaro Videla, Co-author of <<RabbitMQ in Action>>
  • 31. Coupling and Cohesion Coupling and cohesion are metrics that (roughly) describe how easy it will be to change the behavior of some code. ● Elements are coupled if a change in one forces a change in the other ○ For example, if two classes inherit from a common parent, then a change in one class might require a change in the other. Think of a combo audio system: It's tightly coupled because if we want to change from analog to digital radio, we must rebuild the whole system. If we assemble a system from separates, it would have low coupling and we could just swap out the receiver. "Loosely" coupled features (i.e., those with low coupling) are easier to maintain. ● An element's cohesion is a measure of whether its responsibilities form a meaningful unit ○ For example, a class that parses both dates and URLs is not coherent, because they're unrelated concepts. Think of a machine that washes both clothes and dishes—it's unlikely to do both well. At the other extreme, a class that parses only the punctuation in a URL is unlikely to be coherent, because it doesn't represent a whole concept. To get anything done, the programmer will have to find other parsers for protocol, host, resource, and so on. Features with "high" coherence are easier to maintain.
  • 32. SOLID Principles Single Responsibility Principle (SRP) A class should have only one reason to change. Open Closed Principle (OCP) Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification. Liskov Substitution Principle (LSP) Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program. Interface Segregation Principle (ISP) Many client-specific interfaces are better than one general-purpose interface. Dependency Inversion Principle (DIP) High-level modules should not depend on low-level modules. Both should depend on abstractions. Abstractions should not depend on details. Details should depend on abstractions. Ref: SOLID Principles : The Definitive Guide https://android.jlelse.eu/solid-principles-the-d efinitive-guide-75e30a284dea
  • 33. 如何進行? ◉ 熟悉測試相關API, Mock工具, IDE環境 JUnit, Spring MVC Test Framework, AssertJ, Mockito, ... ◉ 學習測試相關技術:Testing、Refactoring、TDD、ATDD & BDD ○ Test First可以確保測試的高涵蓋率,因為總是先有測試的程式,才有實際的成品 ○ Test First可以確保API的設計完善,因為你是先從 API使用者角度的開始延伸 ○ Test First可以確保程式高模組化,因為如果不先規畫好模組,測試很難進行 Ref: Testing modern web applications http://g00glen00b.be/testing-modern-web-applications/ Spring MVC Test Tutorial http://www.petrikainulainen.net/spring-mvc-test-tutorial/ Test Driven Development 經驗整理 https://ingramchen.io/blog/2014/04/how-i-do-test-driven-development.html
  • 34. xUnit
  • 35. Automating Tests List fixture = new ArrayList(); // fixture should be empty Object element = new Object(); fixture.add(element); // fixture should have one element Ref: JUnit Pocket Guide
  • 36. Automating Tests Step 1: Just Print It! List fixture = new ArrayList(); System.out.println(fixture.size()); Object element = new Object(); fixture.add(element); System.out.println(fixture.size()); Ref: JUnit Pocket Guide
  • 37. Automating Tests Step 2: Print with boolean expr List fixture = new ArrayList(); System.out.println(fixture.size() == 0); Object element = new Object(); fixture.add(element); System.out.println(fixture.size() == 1); Ref: JUnit Pocket Guide
  • 38. Automating Tests Step 3: Test with assertion method void assertTrue(boolean condition) throws Exception { if(!condition) throw new Exception("Assertion failed"); } List fixture = new ArrayList(); assertTrue(fixture.size() == 0); Object element = new Object(); fixture.add(element); assertTrue(fixture.size() == 1); Ref: JUnit Pocket Guide
  • 39. JUnit JUnit is a regression testing framework written by Erich Gamma and Kent Beck. In 1997, Erich Gamma and Kent Beck created a simple but effective unit testing framework for Java, called JUnit. Framework – A framework is a semi-complete application. A framework provides a reusable, common structure that can be shared between applications. Developers incorporate the framework into their own application and extend it to meet their specific needs. Frameworks differ from toolkits by providing a coherent structure, rather than a simple set of utility classes. Erich Gamma is well known as one of the “Gang of Four” who gave us the now classic Design Patterns book. Kent Beck is equally well known for his groundbreaking work in the software discipline known as Extreme Programming. Regression testing is any type of software testing which seeks to uncover regression bugs. Regression bugs occur whenever software functionality that previously worked as desired stops working or no longer works in the same way that was previously planned. Typically regression bugs occur as an unintended consequence of program changes.
  • 40. JUnit is a framework that automates the tedious, repetitive parts of writing tests ◉ Runs tests automatically ◉ Runs many tests together and summarizes the results ◉ Provides a convenient place to collect the tests you’ve written ◉ Provides a convenient place for sharing the code used to create the objects you are going to test ◉ Compares actual results to expected results and reports differences
  • 41. “ When I write automated tests I feel more confident in my work than when I don’t write automated tests. When I program test-first I can have confidence throughout the process, Tests give me confidence that I know what problem I’m trying to solve. - Kent Beck
  • 42. JUnit Annotations Annotation Description @Test public void method() The @Test annotation identifies a method as a test method. @Test(expected = Exception.class) Fails if the method does not throw the named exception. @Test(timeout = 100) Fails if the method takes longer than 100 milliseconds. @Before public void method() This method is executed before each test. It is used to prepare the test environment (e.g., read input data, initialize the class). @After public void method() This method is executed after each test. It is used to cleanup the test environment (e.g., delete temporary data, restore defaults). It can also save memory by cleaning up expensive memory structures. @BeforeClass public static void method() This method is executed once, before the start of all tests. It is used to perform time intensive activities, for example, to connect to a database. Methods marked with this annotation need to be defined as static to work with JUnit. @AfterClass public static void method() This method is executed once, after all tests have been finished. It is used to perform clean-up activities, for example, to disconnect from a database. Methods annotated with this annotation need to be defined as static to work with JUnit. @Ignore or @Ignore("Why disabled") Ignores the test method. This is useful when the underlying code has been changed and the test case has not yet been adapted. Or if the execution time of this test is too long to be included. It is best practice to provide the optional description, why the test is disabled.
  • 43. JUnit Assert Statements Statement Description fail(message) Let the method fail. Might be used to check that a certain part of the code is not reached or to have a failing test before the test code is implemented. The message parameter is optional. assertTrue([message,] boolean condition) Checks that the boolean condition is true. assertFalse([message,] boolean condition) Checks that the boolean condition is false. assertEquals([message,] expected, actual) Tests that two values are the same. Note: for arrays the reference is checked not the content of arrays. assertEquals([message,] expected, actual, tolerance) Test that float or double values match. The tolerance is the number of decimals which must be the same. assertNull([message,] object) Checks that the objects is null. assertNotNull([message,] object) Checks that the objects is not null. assertSame([message,] expected, actual) Checks that both variables refer to the same object. assertNotSame([message,] expected, actual) Checks that both variables refer to different objects.
  • 44. Creating Tests with IntelliJ ◉ Use the intention action ○ Place the cursor on the class name ○ Press Alt+Enter ◉ Use Navigation ○ On the main menu, choose Navigate | Test ○ On the context menu, choose Go to | Test
  • 45. Creating Tests with Eclipse + MoreUnit Ref: Walkthrough for a TDD Kata in Eclipse https://advancedweb.hu/2015/10/27/eclipse_tdd/
  • 46. “ Bowling Game Kata Ref: TheBowlingGameKata http://butunclebob.com/ArticleS.UncleBob.TheBowlingGameKata
  • 47. AssertJ ThoughtWorks Technology Radar - TRIAL (NOV 2017) AssertJ is a Java library that provides a fluent interface for assertions, which makes it easy to convey intent within test code. AssertJ gives readable error messages, soft assertions, and improved collections and exception support. We're seeing some teams default to its use instead of JUnit combined with Hamcrest. NORMAL private void makeNormal(Customer customer) { Order o1 = new Order(); customer.addOrder(o1); OrderLine line1 = new OrderLine(6, Product.find("TAL")); o1.addLine(line1); OrderLine line2 = new OrderLine(5, Product.find("HPK")); o1.addLine(line2); OrderLine line3 = new OrderLine(3, Product.find("LGV")); o1.addLine(line3); line2.setSkippable(true); o1.setRush(true); } FLUENT private void makeFluent(Customer customer) { customer.newOrder() .with(6, "TAL") .with(5, "HPK").skippable() .with(3, "LGV") .priorityRush(); }
  • 48. // entry point for all assertThat methods and utility methods (e.g. entry) import static org.assertj.core.api.Assertions.*; // basic assertions assertThat(frodo.getName()).isEqualTo("Frodo"); assertThat(frodo).isNotEqualTo(sauron); // chaining string specific assertions assertThat(frodo.getName()).startsWith("Fro") .endsWith("do") .isEqualToIgnoringCase("frodo"); // collection specific assertions (there are plenty more) // in the examples below fellowshipOfTheRing is a List<TolkienCharacter> assertThat(fellowshipOfTheRing).hasSize(9) .contains(frodo, sam) .doesNotContain(sauron); // as() is used to describe the test and will be shown before the error message assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);
  • 49. // Java 8 exception assertion, standard style ... assertThatThrownBy(() -> { throw new Exception("boom!"); }).hasMessage("boom!"); // ... or BDD style Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); }); assertThat(thrown).hasMessageContaining("boom"); // using the 'extracting' feature to check fellowshipOfTheRing character's names (Java 7) assertThat(fellowshipOfTheRing).extracting("name") .contains("Boromir", "Gandalf", "Frodo", "Legolas") // same thing using a Java 8 method reference assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getName) .doesNotContain("Sauron", "Elrond"); // extracting multiple values at once grouped in tuples (Java 7) assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name") .contains(tuple("Boromir", 37, "Man"), tuple("Sam", 38, "Hobbit"), tuple("Legolas", 1000, "Elf"));
  • 50. // filtering a collection before asserting in Java 7 ... assertThat(fellowshipOfTheRing).filteredOn("race", HOBBIT) .containsOnly(sam, frodo, pippin, merry); // ... or in Java 8 assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o")) .containsOnly(aragorn, frodo, legolas, boromir); // combining filtering and extraction (yes we can) assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o")) .containsOnly(aragorn, frodo, legolas, boromir) .extracting(character -> character.getRace().getName()) .contains("Hobbit", "Elf", "Man"); // and many more assertions: iterable, stream, array, map, dates (java 7 and 8), path, file, numbers, predicate, optional ...
  • 52. Test Double Test Double Test Double is a generic term for any case where you replace a production object for testing purpose. There are various kinds of double list : Dummy、Fake、 Stub、Mock and Spy. Dummy Objects are passed around but never actually used. Usually they are just used to fill parameter lists. Fake Objects actually have working implementations, but usually take some shortcut which makes them not suitable for production. Stub Stub provide canned answers to calls made during the test. Mock Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. Spy Spies are stubs that also record some information based on how they were called. Ref: Martin Fowler - TestDouble https://martinfowler.com/bliki/TestDouble.html
  • 53. Mockito Mockito is a mocking framework for unit tests in Java. It has been designed to be intuitive to use when the test needs mocks. Verify interactions import static org.mockito.Mockito.*; // mock creation List mockedList = mock(List.class); // using mock object - it does not throw any "unexpected interaction" exception mockedList.add("one"); mockedList.clear(); // selective, explicit, highly readable verification verify(mockedList).add("one"); verify(mockedList).clear(); Stub method calls // you can mock concrete classes, not only interfaces LinkedList mockedList = mock(LinkedList.class); // stubbing appears before the actual execution when(mockedList.get(0)).thenReturn("first"); // the following prints "first" System.out.println(mockedList.get(0)); // the following prints "null" because get(999) was not stubbed System.out.println(mockedList.get(999));
  • 54. List<String> mockedList = mock(List. class); //using mock mockedList.add("once"); mockedList.add("twice"); mockedList.add("twice" ); mockedList.add("three times"); mockedList.add("three times"); mockedList.add("three times"); /** * 基本的驗證方法 * verify方法驗證mock對像是否有沒有調用mockedList.add("once")方法 * 不關心其是否有返回值,如果沒有調用測試失敗。 */ verify(mockedList).add("once"); //默認調用一次,times(1)可以省略 verify(mockedList, times(1)).add("once"); verify(mockedList, times(2)).add("twice"); verify(mockedList, times(3)).add("three times"); //never()等同於time(0),一次也沒有調用 verify(mockedList, times(0)).add("never happened"); //atLeastOnece/atLeast()/atMost() verify(mockedList, atLeastOnce()).add("three times"); verify(mockedList, atLeast(2)).add("twice"); verify(mockedList, atMost(5)).add("three times"); 參數匹配器 //stubbing using built-in anyInt() argument matcher when(mockedList.get(anyInt())).thenReturn("element"); //stubbing using custom matcher (let's say isValid() returns your own matcher implementation): when(mockedList.contains(argThat(isValid()))).thenReturn( "element"); //following prints "element" System.out.println(mockedList.get(999)); //you can also verify using an argument matcher verify(mockedList).get(anyInt());
  • 55. “ Inside every well-written large program is a well-written small program. - Charles Antony Richard Hoare, computer scientist
  • 56. Reference ◉ Effective Tests https://lostechies.com/derekgreer/2011/03/07/effective-tests-introduction/ ◉ 30天快速上手TDD https://dotblogs.com.tw/hatelove/2013/01/11/learning-tdd-in-30-days-catalog-and-reference ◉ Coding Dojo http://www.codingdojo.org/KataCatalogue/ ◉ 五分钟让你彻底了解TDD、ATDD、BDD&RBE https://mp.weixin.qq.com/s?__biz=MjM5ODczMDc1Mw==&mid=2651844175&idx=1&sn=c6b17d9dc7ab0f4169e91 49df33d0fb6
  • 57. Any questions ? You can find me at ◉ swanky.hsiao@gmail.com Thanks!