Testing Para Vagos
A brief introduction

"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
No silver bullets
What is testing about?
Getting feedback,
as much frequent as we can
the sooner, the better
Taxonomy


Small
Medium
Large

Test by Scope


Unit Tests
Dependency Injection
- Dependency:
A depends on B when A needs B to do its job -
Injection:
Oject which uses (creates) A tells A who is B
Dependency Injection


VS
Test doubles
Test doubles (Fake)

Fake implenmentation just to make test pass
Test doubles (Stub)
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test.


Ruby (rspec)
Javascript (sinon)
Test doubles (Spy)
Spies are objects that also record some information based on how they were called

Test doubles (Mock)

Informal: think in a Stub which is also a Spy.
It also responds with default values to non-explicitly declared methods


PHP (phpunit)
Ruby (rspec-mock)
Javascript (sinon)
Integration test which want to be a unit test

FIRST(it)
-
Fast
Hundred or thousands per second -
Isolates
Failure reasons become obvious -
Repeatable
Any order, any time -
Self-validating
No manual execution required -
Timely
Written before code -
Inmutable*
SUT is in the same state after execute the tests -
Trusted*
When test fails is because the system fails and viceversa
Integration test which works with external system

Integration test which uses the UI

System Test

Who, when and where run the tests?
-
Unit
- Owner: developer
- When: after every change
- Where: every computer
-
Integration
- Owner: developer || QA team
- When: as part or after commit stage
- Where: devel and pre-pro environments
-
System
- Owner: QA team
- When: as part or after commit stage
- Where: devel and pre-pro environments
Automatic Testing
4 phases-tests
- Set Up
- Exercise
- Verify
- TearDown
What we need?
-
Runner
- Execution
- Reporting
- Assertion framework
Testing framewok families
-
X-Unit
- @Before(Class)
- @Test
- @After(Class)
-
Rspec
-
describe
- beforeEach
- it
- afterEach
-
describe
-
Specification by example (aka BDD)
- Given
- When
- Then
XUnit


Java (Junit)
PHP (phpUnit)
RSpec (suite per class)


Node/Javascript (mocha/jasmine)
Ruby (rspec)
RSpec (suite per setup)

BDD (specification)

BDD (specification)


Ruby (cucumber)
Java (cucumber)
TIPS & TRICKS
Questions & Stupid Questions
- ¿Where I place my tests?
- ¿Who tests the classes which test our classes?
- ¿Could you be able to rewrite the code only reading the tests definitions?
- I spend more time writing code to setup my SUT than writing the test, how do you solve it?
- ¿What is the minimum coverage should I expect for my code?
- I’ve never write a test ¿where can I start?
- My code is not testable at all, ¿what can I do?
- How do I run my tests?
¿Where I place my tests?
-
Unit tests:
- Test Class per Class
- Test Class per SetUp (useful in Xunit frameworks)
- Important naming convention (<ClassName>Test, <TestSuite>IntegrationTest, …)
-
System tests:
- Different project
¿Where I place my tests?
Java Project (Test Class per Class)
MyProject/
src/
main/
java/
com.groupId.artifactId.MyClass.java
resources/
test/
java/
com.groupId.artifactId.MyClassTest.java
com.groupId.artifactId.it.suite.MyTestCaseIntegrationTest.java
resources/
Java Project (Class per SetUp)
MyProject/
src/
main/
…
test/
java/
com.groupId.artifactId.myclass.<SetUp1>Test.java
com.groupId.artifactId.myclass.<SetUp2>Test.java
…
¿Where I place my tests?
Android Project
MyProject/
AndroidManifest.xml
res/
... (resources for main application)
src/
... (source code for main application) ...
tests/
AndroidManifest.xml
res/
... (resources for tests)
src/
... (source code for tests)
NodeJs Project
MyProject/
lib/
myClass.js
main.js
test/
ut/
/suite
it/
lib/
myClassTest.js
IOS Project
MyIOSProject/
MyIOSProject/
... app code ...
MyIOSProjectTests/
... test code ...
¿Who tests the classes which test our classes?
Exactly, this is why it's so important our tests follow
KISS
¿Could you be able to rewrite the code only reading the tests definitions?


Tests, specially Black Box tests, should tell us an story
Well defined and complete scenarios for Acceptance Tests
I spend more time writing code to setup my SUT than writing tests. How do you solve it?
-
Read about fixtures (
XUNIT Patterns is a good reference)- Fresh fixtures
- Shared fixtures
- Persistent fixtures
I duplicate too much code on objects creation, mocks definition and assertions

-
Writing a lot of
code to initialize value objects?-
Create MotherObjects/DataBuilders
-
Create MotherObjects/DataBuilders
-
Writing a lot of
code to initialize mock/stub objects?- Create MockMotherObjects/MockBuilders
-
Writing a lot of
asserts (more purist says only one assertion)?- Create CustomAsserts

I’ve never write a test ¿where can I start?

My code is not testable at all,
what can I do?
- First of all, go to http://refactoring.com/
-
I suggest:
- Add integration regression test.
-
Remove new from methods and
ad it to constructors (this will prepare your class for dependency injection). - Creates a constructor which receive every dependency your class will need.
- Remove static classes and methods (adding the new non-static as a class dependency).
-
Add as
much tests as you want to ;)
Important!!! Do it
How do I run my tests?
-
Java / Android
- $ mvn test
- $ gradle test
-
Ruby
- $ rake test
-
Php
- $ phpunit <testFolder/File>
-
NodeJs
- $ npm test
- $ grunt test
-
Javascript
- $ karma start
Thanks!!!!!
Q&A
Testing Para Vagos
By Sergio Arroyo
Testing Para Vagos
- 1,403