The document discusses test-driven development (TDD) and behavior-driven development (BDD). It explains that TDD relies on writing tests before code to verify requirements and that BDD combines TDD techniques with domain-driven design principles. An example of writing unit tests for a Task struct in Swift using the Xcode testing framework is provided, demonstrating the TDD process of writing a failing test, then code to pass the test, and refactoring.
3.
TechFest Bucharest, Sept 2018 @pardel
TDD
according to Wikipedia
“Test-driven development (TDD) is a software development process
that relies on the repetition of a very short development cycle:
requirements are turned into very specific test cases, then the
software is improved to pass the new tests, only. This is opposed
to software development that allows software to be added that is not
proven to meet requirements.”
https://en.wikipedia.org/wiki/Test-driven_development
6.
TechFest Bucharest, Sept 2018 @pardel
BDD
according to Wikipedia
"combines the general techniques and principles of TDD with ideas
from domain-driven design and object-oriented analysis and design
to provide software development and management teams with
shared tools and a shared process to collaborate on software
development."
https://en.wikipedia.org/wiki/Behavior-driven_development
10.
TechFest Bucharest, Sept 2018 @pardel
TDD lifecycle
Feature, Red, Green, Refactor
Pick a feature to implement
making sure it’s a small enough unit.
FEATURE
Change any of the existing code
making sure ALL tests are passing.
REFACTOR
Write a failing test.
Stop as soon as you get a failure.
RED
Write code to pass the test.
Write as little code as possible.
GREENL (
)
11.
TechFest Bucharest, Sept 2018 @pardel
TDD lifecycle
Feature, Red, Green, Refactor
New
feature
create test
enough code to
make it pass
successful
test execution
No
anything to
refactor
Yes
Yes
refactoring
No
Ya Ain’t Gonna Need It
78.
TechFest Bucharest, Sept 2018 @pardel
Pick good test names
test_init_takesTitleAndDescription()
test_ValidAccountName_InvalidAccountNumber_ValidSortCode_CurrentAccoun
t_OneOwner_CanNotBeInstantiated()
79.
TechFest Bucharest, Sept 2018 @pardel
Pick good names
SUT
func testLogoutCallsDelegateMethod() {
// Given
guard let sut = sut else {
XCTFail("Could not get system under test")
return
}
// When
delegateStatus = .noneCalled
sut.logout()
// Then
XCTAssertTrue(delegateStatus == .didLogoutCalled, "delegate method was not called")
}
82.
TechFest Bucharest, Sept 2018 @pardel
Input & output in one place
func testCanCreateATask() {
let name = UUID().uuidString
let task = Task(name: name)
XCTAssertNotNil(task)
XCTAssertEqual(task?.name, name)
}
87.
TechFest Bucharest, Sept 2018 @pardel
BDD
Quick & Nimble
import Quick
import Nimble
class TableOfContentsSpec: QuickSpec {
override func spec() {
describe("the 'Documentation' directory") {
it("has everything you need to get started") {
let sections = Directory("Documentation").sections
expect(sections).to(contain("Organized Tests with Quick Examples and Example Groups"))
expect(sections).to(contain("Installing Quick"))
}
context("if it doesn't have what you're looking for") {
it("needs to be updated") {
let you = You(awesome: true)
expect{you.submittedAnIssue}.toEventually(beTruthy())
}
}
}
}
}
88.
TechFest Bucharest, Sept 2018 @pardel
FitNesse
http://fitnesse.org
package fitnesse.slim.test;
public class ShouldIBuyMilk {
private int dollars;
private int pints;
private boolean creditCard;
public void setCashInWallet(int dollars) {
this.dollars = dollars;
}
public void setPintsOfMilkRemaining(int pints) {
this.pints = pints;
}
public void setCreditCard(String valid) {
creditCard = "yes".equals(valid);
}
public String goToStore() {
return (pints == 0 && (dollars > 2 || creditCard)) ? "yes" : "no";
}
// The following functions are optional. If they aren't declared they'll be ignored.
public void execute() {
}
public void reset() {
}
public void table(List<List<String>> table) {
}
public void beginTable() {
}
public void endTable() {
}
}