Transcript

Writing clean and DRY

infrastructure test code

Vagif Abilov, Miles AS

About myself

Mail: vagif.abilov@gmail.com

Twitter: @ooobject

GitHub: object

BitBucket: object

Blog:

http://bloggingabout.net/blogs/vagif/default.aspx

Articles: http://www.codeproject.com

Agenda

How good is test code? Or how bad?

Testers as first class citizens

10 steps that lead to cleaner test code

Case studies and examples

How good is test code? Or how bad?

What quality do you expect from test code?

Test code tends to have inferior quality comparing to

production code

Test code tends to have superior quality comparing to

production code

Test and production code tend to have same quality

How long is a test’s lifetime?

Test code lasts as long as production code

Test code can be discarded while production code is still

in use

Test code can outlive production code

Testers as first class citizens

Anything that is deployed to production or shipped to customers is subject to more rigid requirements than internal matters

Product internals are external matters, test internals are internal matters

Software testers’ choices of tools and languages usually meet more liberal reception by management and principal architects

There is no excuse for a tester of not turning liberal management attitude to his/her own advantage –software testers have better chances to adopt most recent methods and technology

10 steps that lead to cleaner test code

1. Bridge communication gap

2. Use executable specifications

3. Let actors act in scenario definitions

4. «Push HOW down the stack»

5. Reduce translation layers

6. Practice explorative scripting

7. Expose test automation frameworks

8. DRY – explore community

9. Embrace dynamic languages

10. Care only about persistent state that matters

1. Bridge communication gap

“BDD is a 2nd generation, outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, Agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.” – Dan North

“BDD is not primarily a testing thing. You happen to get tests out of it afterwards, but there's usually still more testing that needs to be done. It's much more about developing an understanding of what you're about to produce.” – Liz Keogh

“Conversations are much more important than the BDD tools.” – Liz Keogh

2. Use executable specifications

Scenario: The answer with the highest vote gets to the

top

Given there is a question «What is your favourite

color» with the answers

| Answer | Vote |

| Red | 1 |

| Green | 1 |

When I upvote the answer «Green»

Then the answer «Green» should be on the top

Advantages of executable specifications

Written in a natural language (and local language)

Written in a formalised way

Integrated into daily builds

Living documentation

Set development milestones

Functional coverage

Functional coverage

Examples of executable specifications

Relish

Publishing executable specifications on the web

Examples: GDS/whitehall

brighterplanet/flight

3. Let actors act in scenario definitionsFeature: Pay bill

Background: Prices

Given the following operations are available:

| operation | price |

| routine check up | 10 |

| shots | 5 |

Scenario: Dave pays for Fluffy

Given Dave owns a pet Fluffy

And Dave brings Fluffy into the clinic for the following operations:

| routine check up |

| shots |

When the veterinarian charges Dave for the visit

And Dave pays cash

Then Dave is given a receipt which looks like this:

Operations:

$10 (routine check up)

$5 (shots)

Total to pay: $15 from Mann Wynne’s blog

Real world example

Adding an actor to a scenario

Distributing election reports

Scenario: Received report is saved and notification message is enqueued

Given table RP07 doesn’t contain reports for 46010000

And notification queue is empty

When receival service receives report RP07 with data

| Element | Value |

| dateCreated | 2013-05-01T10:01:02 |

| identifier | 46010000 |

| mandates | Ap=6;H=5;V=4 |

Then receival service should return OK

And table RP07 should contain report for 46010000

And notification queue should contain message

| Code | Identifier | Mandates |

| RP07 | 46010000 | Ap=6;H=5;V=4 |(Code example 1)

Revised scenario

Scenario: Parliament overview is updated shortly upon the report receival

Given I see following Parliament party mandates overview| Party | Mandates || Ap | 3 || H | 2 || V | 1 |

When receival service receives report RP07 with data| Party | Mandates || Ap | 6 || H | 5 || V | 4 |

And I wait 10 seconds

Then I should see following Parliament party mandates overview| Party | Mandates || Ap | 6 || H | 5 || V | 4 |

4. «Push HOW down the stack»

As said by Seb Rose and Matt Wynne

Gojko Adzic defines three levels of UI test automation- business/rule- user interface/workflow- technical

Specifications reflect a problem domain

From Matt Wynne’s blog

5. Reduce translation layers

BDD fixtures translate between system concepts

and user concepts. The more work the fixtures do,

the more wrong your system is

@richardadalton

Finding most efficient feature

implementation language

Scenario: Refunded items should be returned to stock

Given a customer buys a black jumper

And I have 3 black jumpers left in stock

When he returns the jumper for a refund

Then I should have 4 black jumpers in stock

Step definition examples

1. C#/SpecFlow

2. Ruby

3. F#/TickSpec

(Code examples 2-4)

6. Practice explorative scripting

Don’t rush building test automation framework before

you explore the system

Try finding REPL tool for the language of your tests

Explore the system from script sessions

Use exploration results to build automated tests

Beware that manual test scripts and automated tests

carry different contexts and usually can’t be easily

substituted

DEMO

Web UI scripting using

scriptcs and FluentAutomation

7. Expose test automation frameworks

If you have WebDriver APIs in your test methods,

you're doing it wrong (Simon Stewart)

UI

Tests Tests

UI

Automatio

n

API

«Page» in PageObject can be misleading

Despite the term "page" object, these objects

shouldn't usually be built for each page, but rather

for the significant elements on a page (Martin

Fowler)

Fowler also gives an alternative name: Panel

In general PageObject classes in UI automation

library should not bear names of HTML pages

Rather than exposing logical page control API you

can model a test automation framework after user’s

behavior

Example: Google search automation

Feature: Search for professional events

In order to keep updated about professional events

As a service subscriber

I want to be able to search for conferences

Scenario: Search for professional conference Web sites

Given I am a service subscriber

When I search for "Agile Testing Days"

Then I should receive results starting with "www.agiletestingdays.com"

Page pattern vs. behavioral pattern

Page pattern fits well regression tests and

automation of external Web sites

Behavioral pattern focuses on high level user

activities and can be easier to apply when Web site

structure is subject to major changes

(Code examples 5-8)

8. DRY – explore community

In fact it’s not just about DRY – it’s DRO (Don’t

Repeat Others)

There’s plenty of libraries (mostly open-source) that

have already solved your plumbing needs

Generating of pseudo-random test data

Converting Gherkin tables to DTOs

Comparing Gherkin tables with contents of data sources

Replacing DTOs with dynamic objects

Example: user data validation

Scenario: Validate users

Given the following users exists in the database:

| Name | Birth date | Length in meters|

| John | 1940-10-09 | 1.80 |

| Paul | 1942-06-18 | 1.80|

| George | 1943-02-25 | 1.77 |

| Ringo | 1940-07-07 | 1.68 |

Then the following users must exist in the database:

| John | 1940-10-09 | 1.80 |

| Paul | 1942-06-18 | 1.80|

| George | 1943-02-25 | 1.77 |

| Ringo | 1940-07-07 | 1.68 |

(Code examples 9-12)

9. Embrace dynamic languages

Less ceremony – more action

Access databases without creating proxy classes

and DTOs

Access Web services without importing WSDL files

Eliminate data transfer objects

Code examples 13-15)

10. Care only about persistent state that matters

Don’t set expectations about persistent state for the

test

Don’t restore persistent state after the test

Don’t take an effort of complex data deletion routines

Just push aside data that stand on the way of your

test

Code examples (16-17)

Once again...

1. Bridge communication gap

2. Use executable specifications

3. Let actors act in scenario definitions

4. Push HOW down

5. Reduce translation layers

6. Practice explorative scripting

7. Expose test automation frameworks

8. DRY – explore community

9. Embrace dynamic languages

10. Care only about persistent state that matters

Karaoke time!

«Beautiful Code»

Christina Agile-Era

Writing clean and DRY infrastructure test code

Thank you!

Vagif Abilov

vagif.abilov@gmail.com

@ooobject

GitHub: object

BitBucket: object

top related