SlideShare a Scribd company logo
1 of 28
Download to read offline
TESTING WITHOUT
WRITING TESTS
HAVING FUN WITH POSTCODES AND LIES
VICTOR MUNOZ
WHAT'S IN A
POSTCODE?
A typical British postcode has a clearly defined
structure...
...but many possible variations
Writing a correct regular expression is feasible, but tricky
So, so many cases to test against
W1 6LS
N1C 4AQ
N17 6LA
SW8 1UQ
WC2H 7LT
HU12 0AR
THE BAD, THE WRONG
AND THE UGLY
There is a list of official rules
Even a (wrong) regexp in an official document
THE WRONG
^([Gg][Ii][Rr] 0[Aa]{2}) |
(
(
([A-Za-z][0-9]{1,2}) |
(
([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2}) |
(
([AZa-z][0-9][A-Za-z]) |
([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])
)
)
) [0-9][A-Za-z]{2})$
No, this is not LISP. Promise.
THE BAD
^(
([gG][iI][rR] {0,}0[aA]{2}) |
(
(
([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?) |
(
([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW]) |
([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y])
)
) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2}
)
)$
THE UGLY
^(?P<postcode>
(?P<girobank>girs*0aa) | # Girobank.
(
(?P<first>
((?![qvx])[a-z][a-hk-y]?[0-9][0-9]?) | # First part.
((?![qvx])[a-z][0-9][a-hjkpstuw]) | # First part.
((?![qvx])[a-z][a-hk-y][0-9][abehmnprvwxy]) # First part.
)s*(?P<second>[0-9](?![cikmov])[a-z]{2})? # Second part.
)
)$
...but it's my ugly.
HOW DO I TEST THAT?
Carefully
Create lots of cases
Cover all possibilities of success and failure
TL; DR: Hell
CAN I HAVE SOME
MAGIC?
Since you ask nicely...
Let's use pytest to generate tests from the test dataset
Note for testing nerds: Yes, this is just a semi-magic form
of table-driven tests.
TESTING STRATEGY (I)
1. Check if the postcode matches
2. Check it matches the right thing
3. Check the first part is matched correctly
4. Check the second part is matched correctly
class ValidPostcodeTests:
def test_match(self, data, postcode, first, second):
assert pattern.match(data)
def test_groups(self, data, postcode, first, second):
assert pattern.match(data).group('postcode') == postcode
assert pattern.match(data).group('first') == first
assert pattern.match(data).group('second') == second
TESTING STRATEGY(II)
For invalid postcodes, just check it doesn't match
class TestInvalidPostcode:
def test_match(self, data, postcode, first, second):
assert pattern.match(data) is None
TESTING STRATEGY (III)
Test for variations as well:
Lowercase postcodes
Postcodes without space separator
Partial postcodes
Any combination of those
transforms = {
"lowercase": partial(
_transform_factory,
lambda k: k.lower() if k else k
),
"nospace": partial(
_transform_factory,
lambda k: k.replace(' ', '') if k else k
),
}
Once you have all the combinations, generate tests.
class DataGenerator:
def generate_data(self):
for item in self.dataset:
for transform in self._get_transform_combinations():
yield self._transform_data(item, *transform)
def generate_ids(self):
for item in self.dataset:
for transform in self._get_transform_combinations():
yield "{}-{}".format(
item[0].replace(" ", "_"),
"_".join(transform) or "original"
)
Finally, hook that into pytest
def pytest_generate_tests(metafunc):
if metafunc.cls:
gen = DataGenerator(metafunc.cls.postcodes)
metafunc.parametrize(
'data,postcode,first,second',
list(gen.generate_data()),
ids=list(gen.generate_ids()),
scope='class'
)
Your test cases should look like this:
class TestFullPostcodes(ValidPostcodeTests):
postcodes = (
("W1 6LS", "W1 6LS", "W1", "6LS",),
("N1C 4UQ", "N1C 4UQ", "N1C", "4UQ",),
("N1P 4AA", "N1P 4AA", "N1P", "4AA",),
("N17 6LA", "N17 6LA", "N17", "6LA",),
("SW8 1UQ", "SW8 1UQ", "SW8", "1UQ",),
("CW3 9SS", "CW3 9SS", "CW3", "9SS",),
("SE5 0EG", "SE5 0EG", "SE5", "0EG",),
("WC2H 7LT", "WC2H 7LT", "WC2H", "7LT",),
("WC1N 2PL", "WC1N 2PL", "WC1N", "2PL",),
("HU12 0AR", "HU12 0AR", "HU12", "0AR"),
)
I WANT TO COVER
EVERYTHING
OS CODEPOINT
1.7M+ postcodes
Covers pretty much everything
First, extract the useful bits in a useful format
def get_postcodes(datadir):
for fn in listdir(datadir):
with open(datadir + fn) as f:
for row in reader(f):
yield row[0]
if __name__ == '__main__':
datadir = 'tests/data/Data/CSV/'
postcodes = list(get_postcodes(datadir))
with open("tests/OSpostcodes.db", "wb") as f:
pickle.dump(postcodes, f, pickle.HIGHEST_PROTOCOL)
Then, generate millions of tests
def pytest_generate_tests(metafunc):
if pytest.config.getoption("osdb"):
with open("tests/OSpostcodes.db", "rb") as f:
metafunc.parametrize("postcode", pickle.load(f))
else:
metafunc.parametrize("postcode", pytest.skip([]))
def test_OS_postcodes(postcode):
assert pattern.match(postcode)
QUESTIONS?
COMMENTS?
victorm@marshland.es
@vmberti
github.com/bolsote/ukpcre

More Related Content

What's hot

The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84Mahmoud Samir Fayed
 
The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.3 book - Part 25 of 88The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.3 book - Part 25 of 88Mahmoud Samir Fayed
 
Java patterns in Scala
Java patterns in ScalaJava patterns in Scala
Java patterns in ScalaRadim Pavlicek
 
CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...
CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...
CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...CodeFest
 
Internship - Final Presentation (26-08-2015)
Internship - Final Presentation (26-08-2015)Internship - Final Presentation (26-08-2015)
Internship - Final Presentation (26-08-2015)Sean Krail
 
The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88Mahmoud Samir Fayed
 
The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202Mahmoud Samir Fayed
 
Interface record comparator
Interface record comparatorInterface record comparator
Interface record comparatormyrajendra
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of LambdasEsther Lozano
 
The Ring programming language version 1.5.2 book - Part 31 of 181
The Ring programming language version 1.5.2 book - Part 31 of 181The Ring programming language version 1.5.2 book - Part 31 of 181
The Ring programming language version 1.5.2 book - Part 31 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 35 of 185
The Ring programming language version 1.5.4 book - Part 35 of 185The Ring programming language version 1.5.4 book - Part 35 of 185
The Ring programming language version 1.5.4 book - Part 35 of 185Mahmoud Samir Fayed
 
The Ring programming language version 1.10 book - Part 44 of 212
The Ring programming language version 1.10 book - Part 44 of 212The Ring programming language version 1.10 book - Part 44 of 212
The Ring programming language version 1.10 book - Part 44 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 34 of 181
The Ring programming language version 1.5.2 book - Part 34 of 181The Ring programming language version 1.5.2 book - Part 34 of 181
The Ring programming language version 1.5.2 book - Part 34 of 181Mahmoud Samir Fayed
 
Google guava - almost everything you need to know
Google guava - almost everything you need to knowGoogle guava - almost everything you need to know
Google guava - almost everything you need to knowTomasz Dziurko
 
The Ring programming language version 1.8 book - Part 40 of 202
The Ring programming language version 1.8 book - Part 40 of 202The Ring programming language version 1.8 book - Part 40 of 202
The Ring programming language version 1.8 book - Part 40 of 202Mahmoud Samir Fayed
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 123 of 210
The Ring programming language version 1.9 book - Part 123 of 210The Ring programming language version 1.9 book - Part 123 of 210
The Ring programming language version 1.9 book - Part 123 of 210Mahmoud Samir Fayed
 

What's hot (20)

Shell sort
Shell sortShell sort
Shell sort
 
The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84The Ring programming language version 1.2 book - Part 21 of 84
The Ring programming language version 1.2 book - Part 21 of 84
 
The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.3 book - Part 25 of 88The Ring programming language version 1.3 book - Part 25 of 88
The Ring programming language version 1.3 book - Part 25 of 88
 
Java patterns in Scala
Java patterns in ScalaJava patterns in Scala
Java patterns in Scala
 
CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...
CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...
CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environment...
 
Internship - Final Presentation (26-08-2015)
Internship - Final Presentation (26-08-2015)Internship - Final Presentation (26-08-2015)
Internship - Final Presentation (26-08-2015)
 
The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88The Ring programming language version 1.3 book - Part 23 of 88
The Ring programming language version 1.3 book - Part 23 of 88
 
The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202The Ring programming language version 1.8 book - Part 37 of 202
The Ring programming language version 1.8 book - Part 37 of 202
 
Interface record comparator
Interface record comparatorInterface record comparator
Interface record comparator
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
 
The Ring programming language version 1.5.2 book - Part 31 of 181
The Ring programming language version 1.5.2 book - Part 31 of 181The Ring programming language version 1.5.2 book - Part 31 of 181
The Ring programming language version 1.5.2 book - Part 31 of 181
 
The Ring programming language version 1.5.4 book - Part 35 of 185
The Ring programming language version 1.5.4 book - Part 35 of 185The Ring programming language version 1.5.4 book - Part 35 of 185
The Ring programming language version 1.5.4 book - Part 35 of 185
 
The Ring programming language version 1.10 book - Part 44 of 212
The Ring programming language version 1.10 book - Part 44 of 212The Ring programming language version 1.10 book - Part 44 of 212
The Ring programming language version 1.10 book - Part 44 of 212
 
The Ring programming language version 1.5.2 book - Part 34 of 181
The Ring programming language version 1.5.2 book - Part 34 of 181The Ring programming language version 1.5.2 book - Part 34 of 181
The Ring programming language version 1.5.2 book - Part 34 of 181
 
Google guava - almost everything you need to know
Google guava - almost everything you need to knowGoogle guava - almost everything you need to know
Google guava - almost everything you need to know
 
Ds stack 03
Ds stack 03Ds stack 03
Ds stack 03
 
Anti patterns
Anti patternsAnti patterns
Anti patterns
 
The Ring programming language version 1.8 book - Part 40 of 202
The Ring programming language version 1.8 book - Part 40 of 202The Ring programming language version 1.8 book - Part 40 of 202
The Ring programming language version 1.8 book - Part 40 of 202
 
The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181The Ring programming language version 1.5.2 book - Part 78 of 181
The Ring programming language version 1.5.2 book - Part 78 of 181
 
The Ring programming language version 1.9 book - Part 123 of 210
The Ring programming language version 1.9 book - Part 123 of 210The Ring programming language version 1.9 book - Part 123 of 210
The Ring programming language version 1.9 book - Part 123 of 210
 

Viewers also liked

A Gazillion Ways To Use A Digital Camera
A Gazillion Ways To Use A Digital CameraA Gazillion Ways To Use A Digital Camera
A Gazillion Ways To Use A Digital Camerailove2doyoga
 
550 Churchgate @ Rs.55,000
550 Churchgate @ Rs.55,000550 Churchgate @ Rs.55,000
550 Churchgate @ Rs.55,000rajshah
 
Link Walking with Riak
Link Walking with RiakLink Walking with Riak
Link Walking with RiakSusan Potter
 
Digging Into Digital Photography
Digging Into Digital PhotographyDigging Into Digital Photography
Digging Into Digital Photographyilove2doyoga
 
Social Bookmarking
Social BookmarkingSocial Bookmarking
Social Bookmarkingilove2doyoga
 
Meeting 2 Presentation
Meeting 2   PresentationMeeting 2   Presentation
Meeting 2 Presentationilove2doyoga
 
Digging Into Digital Photography
Digging Into Digital PhotographyDigging Into Digital Photography
Digging Into Digital Photographyilove2doyoga
 

Viewers also liked (7)

A Gazillion Ways To Use A Digital Camera
A Gazillion Ways To Use A Digital CameraA Gazillion Ways To Use A Digital Camera
A Gazillion Ways To Use A Digital Camera
 
550 Churchgate @ Rs.55,000
550 Churchgate @ Rs.55,000550 Churchgate @ Rs.55,000
550 Churchgate @ Rs.55,000
 
Link Walking with Riak
Link Walking with RiakLink Walking with Riak
Link Walking with Riak
 
Digging Into Digital Photography
Digging Into Digital PhotographyDigging Into Digital Photography
Digging Into Digital Photography
 
Social Bookmarking
Social BookmarkingSocial Bookmarking
Social Bookmarking
 
Meeting 2 Presentation
Meeting 2   PresentationMeeting 2   Presentation
Meeting 2 Presentation
 
Digging Into Digital Photography
Digging Into Digital PhotographyDigging Into Digital Photography
Digging Into Digital Photography
 

Similar to Testing Without Writing Tests

User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryDatabricks
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from javaIndicThreads
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009David Pollak
 
Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in rmanikanta361
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
Microsoft Word Practice Exercise Set 2
Microsoft Word   Practice Exercise Set 2Microsoft Word   Practice Exercise Set 2
Microsoft Word Practice Exercise Set 2rampan
 
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingEelco Visser
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Codemotion
 
An Exploration of the Formal Properties of PromQL
An Exploration of the Formal Properties of PromQLAn Exploration of the Formal Properties of PromQL
An Exploration of the Formal Properties of PromQLBrian Brazil
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test frameworkAbner Chih Yi Huang
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In ScalaSkills Matter
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages VictorSzoltysek
 

Similar to Testing Without Writing Tests (20)

User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
User Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love StoryUser Defined Aggregation in Apache Spark: A Love Story
User Defined Aggregation in Apache Spark: A Love Story
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Scala collections api expressivity and brevity upgrade from java
Scala collections api  expressivity and brevity upgrade from javaScala collections api  expressivity and brevity upgrade from java
Scala collections api expressivity and brevity upgrade from java
 
Beginning Scala Svcc 2009
Beginning Scala Svcc 2009Beginning Scala Svcc 2009
Beginning Scala Svcc 2009
 
Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in r
 
Eta
EtaEta
Eta
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
Pattern Matching in Java 14
Pattern Matching in Java 14Pattern Matching in Java 14
Pattern Matching in Java 14
 
Interpreter Case Study - Design Patterns
Interpreter Case Study - Design PatternsInterpreter Case Study - Design Patterns
Interpreter Case Study - Design Patterns
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Microsoft Word Practice Exercise Set 2
Microsoft Word   Practice Exercise Set 2Microsoft Word   Practice Exercise Set 2
Microsoft Word Practice Exercise Set 2
 
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term RewritingCS4200 2019 | Lecture 5 | Transformation by Term Rewriting
CS4200 2019 | Lecture 5 | Transformation by Term Rewriting
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
An Exploration of the Formal Properties of PromQL
An Exploration of the Formal Properties of PromQLAn Exploration of the Formal Properties of PromQL
An Exploration of the Formal Properties of PromQL
 
Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
 
An introduction to Google test framework
An introduction to Google test frameworkAn introduction to Google test framework
An introduction to Google test framework
 
Rewriting Java In Scala
Rewriting Java In ScalaRewriting Java In Scala
Rewriting Java In Scala
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
The Future of JVM Languages
The Future of JVM Languages The Future of JVM Languages
The Future of JVM Languages
 

Recently uploaded

ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfKamal Acharya
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations120cr0395
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Christo Ananth
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesPrabhanshu Chaturvedi
 
Online banking management system project.pdf
Online banking management system project.pdfOnline banking management system project.pdf
Online banking management system project.pdfKamal Acharya
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Dr.Costas Sachpazis
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduitsrknatarajan
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Bookingdharasingh5698
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingrknatarajan
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Christo Ananth
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)simmis5
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls in Nagpur High Profile
 
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxBSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxfenichawla
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINESIVASHANKAR N
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escortsranjana rawat
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Dr.Costas Sachpazis
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college projectTonystark477637
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls in Nagpur High Profile
 

Recently uploaded (20)

ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdfONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
ONLINE FOOD ORDER SYSTEM PROJECT REPORT.pdf
 
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur EscortsRussian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
Russian Call Girls in Nagpur Grishma Call 7001035870 Meet With Nagpur Escorts
 
Extrusion Processes and Their Limitations
Extrusion Processes and Their LimitationsExtrusion Processes and Their Limitations
Extrusion Processes and Their Limitations
 
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
Call for Papers - Educational Administration: Theory and Practice, E-ISSN: 21...
 
Glass Ceramics: Processing and Properties
Glass Ceramics: Processing and PropertiesGlass Ceramics: Processing and Properties
Glass Ceramics: Processing and Properties
 
Online banking management system project.pdf
Online banking management system project.pdfOnline banking management system project.pdf
Online banking management system project.pdf
 
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
Structural Analysis and Design of Foundations: A Comprehensive Handbook for S...
 
UNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular ConduitsUNIT-II FMM-Flow Through Circular Conduits
UNIT-II FMM-Flow Through Circular Conduits
 
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINEDJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
DJARUM4D - SLOT GACOR ONLINE | SLOT DEMO ONLINE
 
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 BookingVIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
VIP Call Girls Ankleshwar 7001035870 Whatsapp Number, 24/07 Booking
 
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and workingUNIT-V FMM.HYDRAULIC TURBINE - Construction and working
UNIT-V FMM.HYDRAULIC TURBINE - Construction and working
 
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
Call for Papers - African Journal of Biological Sciences, E-ISSN: 2663-2187, ...
 
Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)Java Programming :Event Handling(Types of Events)
Java Programming :Event Handling(Types of Events)
 
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur EscortsCall Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
Call Girls Service Nagpur Tanvi Call 7001035870 Meet With Nagpur Escorts
 
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptxBSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
BSides Seattle 2024 - Stopping Ethan Hunt From Taking Your Data.pptx
 
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINEMANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
MANUFACTURING PROCESS-II UNIT-2 LATHE MACHINE
 
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur EscortsHigh Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
High Profile Call Girls Nagpur Isha Call 7001035870 Meet With Nagpur Escorts
 
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
Sheet Pile Wall Design and Construction: A Practical Guide for Civil Engineer...
 
result management system report for college project
result management system report for college projectresult management system report for college project
result management system report for college project
 
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service NashikCall Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
Call Girls Service Nashik Vaishnavi 7001305949 Independent Escort Service Nashik
 

Testing Without Writing Tests

  • 1. TESTING WITHOUT WRITING TESTS HAVING FUN WITH POSTCODES AND LIES VICTOR MUNOZ
  • 3. A typical British postcode has a clearly defined structure... ...but many possible variations Writing a correct regular expression is feasible, but tricky So, so many cases to test against
  • 4. W1 6LS N1C 4AQ N17 6LA SW8 1UQ WC2H 7LT HU12 0AR
  • 5. THE BAD, THE WRONG AND THE UGLY
  • 6. There is a list of official rules Even a (wrong) regexp in an official document
  • 7. THE WRONG ^([Gg][Ii][Rr] 0[Aa]{2}) | ( ( ([A-Za-z][0-9]{1,2}) | ( ([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2}) | ( ([AZa-z][0-9][A-Za-z]) | ([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z]) ) ) ) [0-9][A-Za-z]{2})$ No, this is not LISP. Promise.
  • 8. THE BAD ^( ([gG][iI][rR] {0,}0[aA]{2}) | ( ( ([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y]?[0-9][0-9]?) | ( ([a-pr-uwyzA-PR-UWYZ][0-9][a-hjkstuwA-HJKSTUW]) | ([a-pr-uwyzA-PR-UWYZ][a-hk-yA-HK-Y][0-9][abehmnprv-yABEHMNPRV-Y]) ) ) {0,}[0-9][abd-hjlnp-uw-zABD-HJLNP-UW-Z]{2} ) )$
  • 9. THE UGLY ^(?P<postcode> (?P<girobank>girs*0aa) | # Girobank. ( (?P<first> ((?![qvx])[a-z][a-hk-y]?[0-9][0-9]?) | # First part. ((?![qvx])[a-z][0-9][a-hjkpstuw]) | # First part. ((?![qvx])[a-z][a-hk-y][0-9][abehmnprvwxy]) # First part. )s*(?P<second>[0-9](?![cikmov])[a-z]{2})? # Second part. ) )$ ...but it's my ugly.
  • 10. HOW DO I TEST THAT?
  • 11. Carefully Create lots of cases Cover all possibilities of success and failure TL; DR: Hell
  • 12. CAN I HAVE SOME MAGIC?
  • 13. Since you ask nicely... Let's use pytest to generate tests from the test dataset Note for testing nerds: Yes, this is just a semi-magic form of table-driven tests.
  • 14. TESTING STRATEGY (I) 1. Check if the postcode matches 2. Check it matches the right thing 3. Check the first part is matched correctly 4. Check the second part is matched correctly
  • 15. class ValidPostcodeTests: def test_match(self, data, postcode, first, second): assert pattern.match(data) def test_groups(self, data, postcode, first, second): assert pattern.match(data).group('postcode') == postcode assert pattern.match(data).group('first') == first assert pattern.match(data).group('second') == second
  • 16. TESTING STRATEGY(II) For invalid postcodes, just check it doesn't match
  • 17. class TestInvalidPostcode: def test_match(self, data, postcode, first, second): assert pattern.match(data) is None
  • 18. TESTING STRATEGY (III) Test for variations as well: Lowercase postcodes Postcodes without space separator Partial postcodes Any combination of those
  • 19. transforms = { "lowercase": partial( _transform_factory, lambda k: k.lower() if k else k ), "nospace": partial( _transform_factory, lambda k: k.replace(' ', '') if k else k ), }
  • 20. Once you have all the combinations, generate tests. class DataGenerator: def generate_data(self): for item in self.dataset: for transform in self._get_transform_combinations(): yield self._transform_data(item, *transform) def generate_ids(self): for item in self.dataset: for transform in self._get_transform_combinations(): yield "{}-{}".format( item[0].replace(" ", "_"), "_".join(transform) or "original" )
  • 21. Finally, hook that into pytest def pytest_generate_tests(metafunc): if metafunc.cls: gen = DataGenerator(metafunc.cls.postcodes) metafunc.parametrize( 'data,postcode,first,second', list(gen.generate_data()), ids=list(gen.generate_ids()), scope='class' )
  • 22. Your test cases should look like this: class TestFullPostcodes(ValidPostcodeTests): postcodes = ( ("W1 6LS", "W1 6LS", "W1", "6LS",), ("N1C 4UQ", "N1C 4UQ", "N1C", "4UQ",), ("N1P 4AA", "N1P 4AA", "N1P", "4AA",), ("N17 6LA", "N17 6LA", "N17", "6LA",), ("SW8 1UQ", "SW8 1UQ", "SW8", "1UQ",), ("CW3 9SS", "CW3 9SS", "CW3", "9SS",), ("SE5 0EG", "SE5 0EG", "SE5", "0EG",), ("WC2H 7LT", "WC2H 7LT", "WC2H", "7LT",), ("WC1N 2PL", "WC1N 2PL", "WC1N", "2PL",), ("HU12 0AR", "HU12 0AR", "HU12", "0AR"), )
  • 23. I WANT TO COVER EVERYTHING
  • 24. OS CODEPOINT 1.7M+ postcodes Covers pretty much everything
  • 25. First, extract the useful bits in a useful format def get_postcodes(datadir): for fn in listdir(datadir): with open(datadir + fn) as f: for row in reader(f): yield row[0] if __name__ == '__main__': datadir = 'tests/data/Data/CSV/' postcodes = list(get_postcodes(datadir)) with open("tests/OSpostcodes.db", "wb") as f: pickle.dump(postcodes, f, pickle.HIGHEST_PROTOCOL)
  • 26. Then, generate millions of tests def pytest_generate_tests(metafunc): if pytest.config.getoption("osdb"): with open("tests/OSpostcodes.db", "rb") as f: metafunc.parametrize("postcode", pickle.load(f)) else: metafunc.parametrize("postcode", pytest.skip([])) def test_OS_postcodes(postcode): assert pattern.match(postcode)