testing untestable code - stpcon11

58
Testing untestable code Stephan Hochdörfer, bitExpert AG

Upload: stephan-hochdoerfer

Post on 10-May-2015

977 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Testing untestable code - STPCon11

Testing untestable codeStephan Hochdörfer, bitExpert AG

Page 2: Testing untestable code - STPCon11

Testing untestable code

About me

Stephan Hochdörfer, bitExpert AG

Department Manager Research Labs

[email protected]

@shochdoerfer

Page 3: Testing untestable code - STPCon11

Testing untestable code

No excuse for writing bad code!

Page 4: Testing untestable code - STPCon11

Not to freak out!

Testing untestable code

Page 5: Testing untestable code - STPCon11

Testing untestable code

Creativity matters!

Page 6: Testing untestable code - STPCon11

Testing untestable code

"There is no secret to writing tests, there are only secrets to write

testable code!" Miško Hevery

Page 7: Testing untestable code - STPCon11

What is „untestable code“?

Testing untestable code

Page 8: Testing untestable code - STPCon11

s

Testing untestable code

Wrong object construction

“new” is evil!

Page 9: Testing untestable code - STPCon11

Testing untestable code

Tight coupling

Page 10: Testing untestable code - STPCon11

Testing untestable code

Uncertainty

Page 11: Testing untestable code - STPCon11

Testing untestable code

"...our test strategy requires us to have more control [...] of the sut."

Gerard Meszaros, xUnit Test Patterns: Refactoring Test Code

Page 12: Testing untestable code - STPCon11

Testing untestable code

SUTSUTUnittestUnittest

In a perfect world...

Page 13: Testing untestable code - STPCon11

Testing untestable code

SUTSUTUnittestUnittest

Legacy code is not perfect...

DependencyDependency

DependencyDependency

Page 14: Testing untestable code - STPCon11

Testing untestable code

SUTSUTUnittestUnittest

Legacy code is not perfect...

DependencyDependency

DependencyDependency

...

...

Page 15: Testing untestable code - STPCon11

Testing untestable code

SUTSUTUnittestUnittest

Legacy code is not perfect...

DependencyDependency

DependencyDependency

...

...

Page 16: Testing untestable code - STPCon11

Testing untestable code

How to get „testable“ code?

Page 17: Testing untestable code - STPCon11

Testing untestable code

How to get „testable“ code?

Refactoring

Page 18: Testing untestable code - STPCon11

Testing untestable code

"Before you start refactoring, check that you have a solid suite of tests."

Martin Fowler, Refactoring

Page 19: Testing untestable code - STPCon11

Testing untestable code

Hope? - Nope...

Page 20: Testing untestable code - STPCon11

Testing untestable code

Which path to take?

Page 21: Testing untestable code - STPCon11

Testing untestable code

Which path to take?

Do not change existing code!

Page 22: Testing untestable code - STPCon11

Testing untestable code

Examples

Object construction External resources Language issues

Page 23: Testing untestable code - STPCon11

Testing untestable code

Object construction

public class Car {private Engine engine;

public Car(String engine) {this.engine = EngineFactory.getByType(engine);

}}

Page 24: Testing untestable code - STPCon11

public class MyLoader extends ClassLoader {protected Class findClass(String name)

throws ClassNotFoundException{

try {String path = name.replace('.', '/');// @TODO: change path and read file, // @TODO: define package// @TODO: define class

}catch(Exception e){

throw new ClassNotFoundException(name);}

}}

Testing untestable code

Object construction - Solution

Page 25: Testing untestable code - STPCon11

Testing untestable code

Object construction - Solution II

<?phpclass MyStreamWrapper { private $_handler;

function stream_open($path, $mode, $options, &$opened_path) { stream_wrapper_restore('file'); // @TODO: modify $path before fopen $this->_handler = fopen($path, $mode); stream_wrapper_unregister('file'); stream_wrapper_register('file', 'MyStreamWrapper'); return true; }}

Page 26: Testing untestable code - STPCon11

Testing untestable code

External resources

Page 27: Testing untestable code - STPCon11

Testing untestable code

External resources

Database Webservice

Filesystem Mailserver

Page 28: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock database

Page 29: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock database

Provide own db driver

Page 30: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock database

junit + dbunit

Page 31: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock database

Proxy for your SQL Server

Page 32: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock webservice

Page 33: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock webservice

Provide own implementation

Page 34: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock webservice

Do not forget!

Url redirection via /etc/hosts

Page 35: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock filesystem

Page 36: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock filesystem

Commons-VFS

vfsStream

Page 37: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock filesystem

<?php

// set up test environmemtvfsStream::setup('exampleDir');

// create directory in test enviromentmkdir(vfsStream::url('exampleDir').'/sample/');

// check if directory was createdecho vfsStreamWrapper::getRoot()->hasChild('sample');

Page 38: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock Mailserver

Page 39: Testing untestable code - STPCon11

Testing untestable code

External resources – Mock Mailserver

Use fake mail server

Page 40: Testing untestable code - STPCon11

Testing untestable code

Dealing with language issues

Page 41: Testing untestable code - STPCon11

Testing untestable code

Dealing with language issues

Testing your privates?

Page 42: Testing untestable code - STPCon11

Testing untestable code

Dealing with language issues

final Method methods[] =o.getClass().getDeclaredMethods();for (int i = 0; i < methods.length; ++i) {

if (methodName.equals(methods[i].getName())) {try {

methods[i].setAccessible(true); return methods[i].invoke(o, params);} catch (IllegalAccessException ex) {}catch (InvocationTargetException ite) {}

}return null;

}

Page 43: Testing untestable code - STPCon11

Testing untestable code

Dealing with language issues

Overwrite internal functions?

Page 44: Testing untestable code - STPCon11

Testing untestable code

What else?

Page 45: Testing untestable code - STPCon11

What else?

Testing untestable code

Generative Programming

Page 46: Testing untestable code - STPCon11

Testing untestable code

Generative Programming

ConfigurationConfiguration

Implementationcomponents

Implementationcomponents

Generatorapplication

Generatorapplication

ProductProductGeneratorGenerator

1 ... n

Page 47: Testing untestable code - STPCon11

Testing untestable code

Generative Programming

ConfigurationConfiguration

Implementationcomponents

Implementationcomponents

Generatorapplication

Generatorapplication

GeneratorGenerator

ApplicationApplication

TestcasesTestcases

Page 48: Testing untestable code - STPCon11

Testing untestable code

Generative Programming

A frame is a data structure for representing knowledge.

Page 49: Testing untestable code - STPCon11

Testing untestable code

A Frame instance

public class Car {private Engine engine;

public Car(String engine) {this.engine = <!{Factory}!>.getByType(engine);

}}

Page 50: Testing untestable code - STPCon11

Testing untestable code

The Frame controller

public class MyFrameController extendsSimpleFrameController {

public void execute(Frame frame, FeatureConfigconfig) {

if(config.hasFeature("unittest")) { frame.setSlot("Factory", "FactoryMock");}else { frame.setSlot("Factory", "EngineFactory");}

}}

Page 51: Testing untestable code - STPCon11

Testing untestable code

Generated result - Testcase

public class Car {private Engine engine;

public Car(String engine) {this.engine = FactoryMock.getByType(engine);

}}

Page 52: Testing untestable code - STPCon11

Testing untestable code

Generated result - Application

public class Car {private Engine engine;

public Car(String engine) {this.engine = EngineFactory.getByType(engine);

}}

Page 53: Testing untestable code - STPCon11

Testing untestable code

What is possible?

Page 54: Testing untestable code - STPCon11

Testing untestable code

What is possible?

Show / hide parts of the code

Page 55: Testing untestable code - STPCon11

Testing untestable code

What is possible?

Change content of global vars!

Page 56: Testing untestable code - STPCon11

Testing untestable code

What is possible?

Define pre- or postfixes!

Page 57: Testing untestable code - STPCon11

Testing untestable code

Is it worth it?

Page 58: Testing untestable code - STPCon11

Thank you for attending this session.

Please fill out an evaluation form.