Jan. 19th 2016 – viscaweb.com/meetings
I'll be presenting some old knowledge sprinkled with personal opinions and experiences
I'll try to present the pros and cons of everything we talk about
This is my take on this subject, I may be wrong in several points. Please feel free to voice your opinion and challenge my words!
#TDD
Software testing is an investigation conducted to provide stakeholders with information about the quality of the product or service under test."
#TDD
#TDD
less fun time debugging :(
#TDD
Ideas?
Why isn't everybody using them?
#TDD
They increase the initial cost, but reduce the cost of maintenance and change
Time/project constraints prevent us, but bugs will slow us down even more if we don't have them
Code that was not designed to be tested is difficult to test, but... fuck
#TDD
In order to refactor, we need to be sure that we are not breaking anything. We need tests to do so.
But in order to be able to test the code, we have to refactor.
We could do end-to-end tests, but that would stop our development efforts for months.
#TDD
final class Greeter
{
public function greet(string $name): void {
echo "Hi {$name}!";
}
}
$greeter = new Greeter();
$greeter->greet('Ricard');
"Code that was not designed to be tested is difficult to test"
#TDD
final class Greeter
{
public function greet(string $name): void {
echo "Hi {$name}!";
}
}
/** @test */
public function can_greet_a_particular_person()
{
$greeter = new Greeter();
$greeter->greet('Ricard');
$this->assertEquals('Hi Ricard!', $output);
}
#TDD
interface Printer {
public function output(string $value): void;
}
final class ConsolePrinter implements Printer {
public function output(string $value): void {
echo $value;
}
}
final class Greeter
{
/** @var Printer **/
private $printer;
public function __construct(Printer $printer) {
$this->printer = $printer;
}
public function greet(string $name): void {
$this->printer->output("Hi {$name}!");
}
}
#TDD
// Test code (w/ PHPUnit mocks)
$printer = $this->getMock(Printer::class);
$printer->expect($this->once())
->method('output')
->with('Hi Ricard!');
$greeter = new Greeter($output);
$greeter->greet('Ricard');
// Test code (w/ Prophecy)
$printer = $this->prophesize(Printer::class);
$greeter = new Greeter($printer->reveal());
$greeter->greet('Ricard');
$printer->output('Hi Ricard!')->shouldHaveBeenCalled();
// Production code
$greeter = new Greeter(new ConsolePrinter());
$greeter->greet('Ricard');
Why isn't everybody using them?
#TDD
They require experience katas!
They require knowledge ViscaMeetings, books, articles, talks
Even with some knowledge and experience, some areas are difficult to test Reduce the confidence by increasing abstraction. Tests will run faster, will be faster to write, but we'll be testing in different levels of abstraction.
#TDD
"Even with some knowledge and experience, some areas are difficult to test"
Let's pretend that we work for an elevator company.
How would we test the different combinations of floors?
#TDD
Which tests would give you the most confidence?
Which would be "good enough" while being fast to run and write?
How would you fake some situations which you cannot easily recreate in real life (closed floor, underground, etc.)?
#TDD
#TDD
Think about what you are going to test
Write a test
Wonder if the test is correct (rewrite until it is)
Run the test: red
Write the simplest implementation possible
Run the test: green
#TDD
/** @test */
public function generates_first_batch_of_numbers()
{
$this->assertEquals(
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31],
generatePrimes()
);
}
#TDD
/** @test */
public function generates_up_to_first_number()
{
$this->assertEquals([2], generatePrimes());
}
// Red
function generatePrimes() {
}
// Green
function generatePrimes(): int[] {
return [2];
}
// Refactor? Not yet
#TDD
/** @test */
public function generates_up_to_second_number()
{
$this->assertEquals([2, 3], generatePrimes());
}
// Red
function generatePrimes(): int[] {
return [2];
}
// Green
function generatePrimes(): int[] {
return [2, 3];
}
// Refactor?
#TDD
Fake it
Obvious implementation
Triangulate
(or third strike and refactor?)
#TDD
Don't try to accomplish too much, you might have to backtrack
Start with small steps, only increase complexity if you feel confident enough
#TDD
Personal experiences with testing
What type of testing do you know, or currently use in LIFE/LIBE?
Why do you think some kinds of test have been discarded in the past?
#TDD
#TDD
#TDD
Testing strategies
#TDD
Testing strategies
#TDD
Testing strategies
#TDD
Testing strategies
#TDD
#TDD
#TDD
#TDD
#TDD
In automated unit testing, it may be necessary to use objects or procedures that look and behave like their release-intended counterparts, but are actually simplified versions that reduce the complexity and facilitate testing. A test double is a generic (meta) term used for these objects or procedures."
#TDD
#TDD
Is a method of software testing that examines the functionality of an application without peering into its internal structures or workings. This method of test can be applied to virtually every level of software testing: unit, integration, system and acceptance. It typically comprises most if not all higher level testing, but can also dominate unit testing as well."
#TDD
(Also known as clear box testing, glass box testing, transparent box testing, and structural testing.)
Is a method of testing software that tests internal structures or workings of an application, as opposed to its functionality (i.e. black-box testing). In white-box testing an internal perspective of the system, as well as programming skills, are used to design test cases."
#TDD
#TDD
Lots more! This is too big of a topic, and will require years of experience, reading, pairing, etc., to discover which things work for you, your organization, your deadlines...
#TDD