SlideShare una empresa de Scribd logo
1 de 29
Descargar para leer sin conexión
Object::Exercise: Keep your objects healthy.
Steven Lembark
Workhorse Computing
lembark@wrkhors.com
Recall that Lazy-ness is a virtue
Hardcoded testing is a pain.
Tests require tests...
Alternative: Data-driven testing.
Declarative specs.
Generated tests.
We have all written this:
Create an object.
Run a command.
Check $@.
Execute a test.
Run a command...
The test cycle
my $obj = $class->new( @argz );
eval
{
my $expect = { qw( your structure from hell ) };
my $found = $obj->foo( @foo_argz );
cmp_deeply $found, $expect, "foo";
};
BAIL_OUT "foo fails" if $@;
eval
{
my $expect = [ { qw( another structure from hell ) } ];
my $found = [ $obj->bar( @bar_argz ) ];
cmp_deeply $found, $expect, "bar";
};
BAIL_OUT "bar fails" if $@;
...
MJD's “Red Flags”
Code is framework, probably updated by cut+paste.
Spend more time hacking framework than module.
Hardwiring the the tests requres testing the tests.
Troubleshooting the tests...
Updating the tests.
Fix: Add a level of abstraction.
Put loops, boilerplate into framework.
Data drives test loop.
Metadata used to generate test data.
Replace hardwired tests with data.
Abstraction: Object::Exercise
A “little language”.
Describe a call, sanity checks.
Data drives the tests.
Array based for simpler processing.
Perl makes this easy
Perl can dispatch $object->$method( ... ).
The $method scalar can be
Text for symbol table dispatch.
Subref for direct dispatch into code.
Text for whitebox, Subref for blackbox.
Planning your exercise.
An array of steps.
Each step is an operation or directive.
Directives are text like “verbose”.
Operations are arrayref's with a
Method + args.
Expect & outcome.
Entering the labrynth
Entry point is a subref.
Avoids namespace collisions with methods:
$object->$exercise( @testz );
initiates testing.
Perly One-Step
Nothing more than a method and arguments:
[
method => arg, ...
]
Executes $obj->$method( arg, … ).
Successful if no exceptions.
Testy Two-Step
Supply fixed return as arrayref:
[
[ method => arg, ... ],
[ compare values ],
]
[ 1 ], [ undef ], [ %struct_from_hell ]
Compared to [ $obj->$method( @argz ) ].
Expecting failure
Testing failure modes raises exceptions.
Explicit undef expects eval { ... } to fail.
Reports successful exception:
[
[ method => @bogus_values ],
undef
]
Saying it your way
Third element is a message:
[
[ $method, @blah_blah ],
[ 42 ],
“$method supplies The Answer”
]
Great expectations
Beyond fixed values: regexen, subrefs.
qr/ ... / $found->[0] =~ $regex ? pass : fail ;
sub { ... } $sub->( @$found ) ? pass : fail ;
Generated regexen, closures simplify testing.
Both can have the optional message.
Giving orders
Directives are text scalars.
Turn on/off verbosity in tests.
Set a breakpoint before calling $method.
Treat input as regex text and compile it.
One-test settings
Text scalars before first arrayref are directives.
Test frobnicate verbosely, rest no-verbose:
noverbose =>
[
verbose =>
[ qw( frobnicate blah blah ) ]
],
One-test breakpoint
Adds $DB::Single = 1 prior to calling $obj->$method.
Simplifies perl -d to check a single method.
[
debug =>
[ qw( foobar bletch blort ) ],
[ 1 ]
]
Regexen in YAML::XS
YAML::XS segfaults handling stored rexen.
“regex” directive compiles expect value as regex:
[
regex =>
[ qw( foobar bletch) ],
'[A-Z]w+$',
]
$obj->foobar( 'bletch' ) =~ qr/[A-Z]w+$/;
Result: Declariative Testing
Tests can be stored in YAML, JSON.
Templates can be expanded in code.
Text methods useful for “blackbox” testing.
Validate what method returns.
Coderef's useful for “whitebox” testing.
Investigate internal structure of object.
Reset incremental values for iterative tests.
Example: Adventure Map Test
Minimal map: One locations entry.
name: Empty Map 00
namespace : EmptyMap00
locations:
blackhole:
name: BlackHole
description : You are standing in a Black Hole.
exits :
Out : blackhole
Generating tests
Starting from the Black Hole:
Validate the description.
Validate move to exit.
Override the map contents
One way: Store separate mission files.
Every test needs to be replicated.
Two way: Replace the map.
Override the method returning locations.
Init reads the map
"add_locations" processes the map:
sub init {
my ($class, $config_path) = @_;
die "You must specify a config file to init()" unless
defined $config_path;
$_config = YAML::LoadFile($config_path);
$class->add_items($_config->{items});
$class->add_actors($_config->{actors});
$class->add_locations($_config->{locations});
$class->add_player('player1', $_config->{player});
}
Adding locations is a loop
They are added one-by-one.
sub add_locations
{
my ($class, $locations) = @_;
foreach my $key (keys %{$locations}) {
$class->add_location($key, $locations->{$key});
}
}
Adding one location
Finally: The root of all evil...
New locations are added with a key and struct:
sub add_location
{
my ($class, $key, $config) = @_;
my $location = Adventure::Location->new;
$location->init($key, $config);
$class->locations->{$key} = $location;
}
Faking the location
sub install_test_location
{
my $package = shift;
my $test_struct = shift;
*{ qualify_to_ref add_location => $package }
= sub
{
my ($class, $key ) = @_;
$class->locations->{$key}
= Adventure::Location
->new
->init($key, $test_struct ); # hardwired map
};
}
Aside: Generic “add” handler
# e.g., install Adventure::Location::add_location
sub add_thingy
{
my ( $parent, $thing ) = @_;
my $name = ‘add_’ . $thing;
my $package = qualify ucfirst(lc $thing), $parent;
*{ qualify_to_ref $name => $package }
= sub
{
my ($class, $name, $data ) = @_;
$class->$type->{$name}
= $package->new->init($name, $data );
};
Summary
Exercising objects is simple, repetitive.
MJD’s “Red Flags”: don’t cut & paste.
Replace hardwired loops with data-driven code.
Object::Exercise standardizes the loops.
Tests are declarative data.

Más contenido relacionado

La actualidad más candente

Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Workhorse Computing
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Kang-min Liu
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Workhorse Computing
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationAttila Balazs
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in PerlLaurent Dami
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlordsheumann
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model Perforce
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Nikita Popov
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Puppet
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring QualityKent Cowgill
 

La actualidad más candente (20)

Memory Manglement in Raku
Memory Manglement in RakuMemory Manglement in Raku
Memory Manglement in Raku
 
Smoking docker
Smoking dockerSmoking docker
Smoking docker
 
Get your teeth into Plack
Get your teeth into PlackGet your teeth into Plack
Get your teeth into Plack
 
Getting Testy With Perl6
Getting Testy With Perl6Getting Testy With Perl6
Getting Testy With Perl6
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
Getting testy with Perl
Getting testy with PerlGetting testy with Perl
Getting testy with Perl
 
Effective Benchmarks
Effective BenchmarksEffective Benchmarks
Effective Benchmarks
 
Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.Perl6 Regexen: Reduce the line noise in your code.
Perl6 Regexen: Reduce the line noise in your code.
 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
 
Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6Ethiopian multiplication in Perl6
Ethiopian multiplication in Perl6
 
Barely Legal Xxx Perl Presentation
Barely Legal Xxx Perl PresentationBarely Legal Xxx Perl Presentation
Barely Legal Xxx Perl Presentation
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 
I, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 OverlordsI, For One, Welcome Our New Perl6 Overlords
I, For One, Welcome Our New Perl6 Overlords
 
Perforce Object and Record Model
Perforce Object and Record Model  Perforce Object and Record Model
Perforce Object and Record Model
 
Perl6 in-production
Perl6 in-productionPerl6 in-production
Perl6 in-production
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...Replacing "exec" with a type and provider: Return manifests to a declarative ...
Replacing "exec" with a type and provider: Return manifests to a declarative ...
 
Testing Code and Assuring Quality
Testing Code and Assuring QualityTesting Code and Assuring Quality
Testing Code and Assuring Quality
 

Similar a Declarative data-driven testing with Object::Exercise

Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScriptniklal
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby MetaprogrammingThaichor Seng
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrowPete McFarlane
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testingVincent Pradeilles
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConRafael Dohms
 
Building a horizontally scalable API in php
Building a horizontally scalable API in phpBuilding a horizontally scalable API in php
Building a horizontally scalable API in phpWade Womersley
 
谈谈Javascript设计
谈谈Javascript设计谈谈Javascript设计
谈谈Javascript设计Alipay
 

Similar a Declarative data-driven testing with Object::Exercise (20)

Damn Fine CoffeeScript
Damn Fine CoffeeScriptDamn Fine CoffeeScript
Damn Fine CoffeeScript
 
DBI
DBIDBI
DBI
 
mro-every.pdf
mro-every.pdfmro-every.pdf
mro-every.pdf
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
Ruby Metaprogramming
Ruby MetaprogrammingRuby Metaprogramming
Ruby Metaprogramming
 
Php & my sql
Php & my sqlPhp & my sql
Php & my sql
 
How to write code you won't hate tomorrow
How to write code you won't hate tomorrowHow to write code you won't hate tomorrow
How to write code you won't hate tomorrow
 
OOP in PHP.pptx
OOP in PHP.pptxOOP in PHP.pptx
OOP in PHP.pptx
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
An introduction to property-based testing
An introduction to property-based testingAn introduction to property-based testing
An introduction to property-based testing
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Your code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnConYour code sucks, let's fix it - DPC UnCon
Your code sucks, let's fix it - DPC UnCon
 
Building a horizontally scalable API in php
Building a horizontally scalable API in phpBuilding a horizontally scalable API in php
Building a horizontally scalable API in php
 
Smelling your code
Smelling your codeSmelling your code
Smelling your code
 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database api
 
Test driven development_for_php
Test driven development_for_phpTest driven development_for_php
Test driven development_for_php
 
谈谈Javascript设计
谈谈Javascript设计谈谈Javascript设计
谈谈Javascript设计
 

Más de Workhorse Computing

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWorkhorse Computing
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpWorkhorse Computing
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlWorkhorse Computing
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.Workhorse Computing
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Workhorse Computing
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Workhorse Computing
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Workhorse Computing
 

Más de Workhorse Computing (15)

Wheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility ModulesWheels we didn't re-invent: Perl's Utility Modules
Wheels we didn't re-invent: Perl's Utility Modules
 
Paranormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add UpParanormal statistics: Counting What Doesn't Add Up
Paranormal statistics: Counting What Doesn't Add Up
 
Generating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in PosgresqlGenerating & Querying Calendar Tables in Posgresql
Generating & Querying Calendar Tables in Posgresql
 
The W-curve and its application.
The W-curve and its application.The W-curve and its application.
The W-curve and its application.
 
Neatly folding-a-tree
Neatly folding-a-treeNeatly folding-a-tree
Neatly folding-a-tree
 
Light my-fuse
Light my-fuseLight my-fuse
Light my-fuse
 
Paranormal stats
Paranormal statsParanormal stats
Paranormal stats
 
Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.Shared Object images in Docker: What you need is what you want.
Shared Object images in Docker: What you need is what you want.
 
Putting some "logic" in LVM.
Putting some "logic" in LVM.Putting some "logic" in LVM.
Putting some "logic" in LVM.
 
Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.Selenium sandwich-3: Being where you aren't.
Selenium sandwich-3: Being where you aren't.
 
Selenium sandwich-2
Selenium sandwich-2Selenium sandwich-2
Selenium sandwich-2
 
Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium Selenium Sandwich Part 1: Data driven Selenium
Selenium Sandwich Part 1: Data driven Selenium
 
Docker perl build
Docker perl buildDocker perl build
Docker perl build
 
Designing net-aws-glacier
Designing net-aws-glacierDesigning net-aws-glacier
Designing net-aws-glacier
 
Lies, Damn Lies, and Benchmarks
Lies, Damn Lies, and BenchmarksLies, Damn Lies, and Benchmarks
Lies, Damn Lies, and Benchmarks
 

Último

WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 

Último (20)

WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 

Declarative data-driven testing with Object::Exercise

  • 1. Object::Exercise: Keep your objects healthy. Steven Lembark Workhorse Computing lembark@wrkhors.com
  • 2. Recall that Lazy-ness is a virtue Hardcoded testing is a pain. Tests require tests... Alternative: Data-driven testing. Declarative specs. Generated tests.
  • 3. We have all written this: Create an object. Run a command. Check $@. Execute a test. Run a command...
  • 4. The test cycle my $obj = $class->new( @argz ); eval { my $expect = { qw( your structure from hell ) }; my $found = $obj->foo( @foo_argz ); cmp_deeply $found, $expect, "foo"; }; BAIL_OUT "foo fails" if $@; eval { my $expect = [ { qw( another structure from hell ) } ]; my $found = [ $obj->bar( @bar_argz ) ]; cmp_deeply $found, $expect, "bar"; }; BAIL_OUT "bar fails" if $@; ...
  • 5. MJD's “Red Flags” Code is framework, probably updated by cut+paste. Spend more time hacking framework than module. Hardwiring the the tests requres testing the tests. Troubleshooting the tests... Updating the tests.
  • 6. Fix: Add a level of abstraction. Put loops, boilerplate into framework. Data drives test loop. Metadata used to generate test data. Replace hardwired tests with data.
  • 7. Abstraction: Object::Exercise A “little language”. Describe a call, sanity checks. Data drives the tests. Array based for simpler processing.
  • 8. Perl makes this easy Perl can dispatch $object->$method( ... ). The $method scalar can be Text for symbol table dispatch. Subref for direct dispatch into code. Text for whitebox, Subref for blackbox.
  • 9. Planning your exercise. An array of steps. Each step is an operation or directive. Directives are text like “verbose”. Operations are arrayref's with a Method + args. Expect & outcome.
  • 10. Entering the labrynth Entry point is a subref. Avoids namespace collisions with methods: $object->$exercise( @testz ); initiates testing.
  • 11. Perly One-Step Nothing more than a method and arguments: [ method => arg, ... ] Executes $obj->$method( arg, … ). Successful if no exceptions.
  • 12. Testy Two-Step Supply fixed return as arrayref: [ [ method => arg, ... ], [ compare values ], ] [ 1 ], [ undef ], [ %struct_from_hell ] Compared to [ $obj->$method( @argz ) ].
  • 13. Expecting failure Testing failure modes raises exceptions. Explicit undef expects eval { ... } to fail. Reports successful exception: [ [ method => @bogus_values ], undef ]
  • 14. Saying it your way Third element is a message: [ [ $method, @blah_blah ], [ 42 ], “$method supplies The Answer” ]
  • 15. Great expectations Beyond fixed values: regexen, subrefs. qr/ ... / $found->[0] =~ $regex ? pass : fail ; sub { ... } $sub->( @$found ) ? pass : fail ; Generated regexen, closures simplify testing. Both can have the optional message.
  • 16. Giving orders Directives are text scalars. Turn on/off verbosity in tests. Set a breakpoint before calling $method. Treat input as regex text and compile it.
  • 17. One-test settings Text scalars before first arrayref are directives. Test frobnicate verbosely, rest no-verbose: noverbose => [ verbose => [ qw( frobnicate blah blah ) ] ],
  • 18. One-test breakpoint Adds $DB::Single = 1 prior to calling $obj->$method. Simplifies perl -d to check a single method. [ debug => [ qw( foobar bletch blort ) ], [ 1 ] ]
  • 19. Regexen in YAML::XS YAML::XS segfaults handling stored rexen. “regex” directive compiles expect value as regex: [ regex => [ qw( foobar bletch) ], '[A-Z]w+$', ] $obj->foobar( 'bletch' ) =~ qr/[A-Z]w+$/;
  • 20. Result: Declariative Testing Tests can be stored in YAML, JSON. Templates can be expanded in code. Text methods useful for “blackbox” testing. Validate what method returns. Coderef's useful for “whitebox” testing. Investigate internal structure of object. Reset incremental values for iterative tests.
  • 21. Example: Adventure Map Test Minimal map: One locations entry. name: Empty Map 00 namespace : EmptyMap00 locations: blackhole: name: BlackHole description : You are standing in a Black Hole. exits : Out : blackhole
  • 22. Generating tests Starting from the Black Hole: Validate the description. Validate move to exit.
  • 23. Override the map contents One way: Store separate mission files. Every test needs to be replicated. Two way: Replace the map. Override the method returning locations.
  • 24. Init reads the map "add_locations" processes the map: sub init { my ($class, $config_path) = @_; die "You must specify a config file to init()" unless defined $config_path; $_config = YAML::LoadFile($config_path); $class->add_items($_config->{items}); $class->add_actors($_config->{actors}); $class->add_locations($_config->{locations}); $class->add_player('player1', $_config->{player}); }
  • 25. Adding locations is a loop They are added one-by-one. sub add_locations { my ($class, $locations) = @_; foreach my $key (keys %{$locations}) { $class->add_location($key, $locations->{$key}); } }
  • 26. Adding one location Finally: The root of all evil... New locations are added with a key and struct: sub add_location { my ($class, $key, $config) = @_; my $location = Adventure::Location->new; $location->init($key, $config); $class->locations->{$key} = $location; }
  • 27. Faking the location sub install_test_location { my $package = shift; my $test_struct = shift; *{ qualify_to_ref add_location => $package } = sub { my ($class, $key ) = @_; $class->locations->{$key} = Adventure::Location ->new ->init($key, $test_struct ); # hardwired map }; }
  • 28. Aside: Generic “add” handler # e.g., install Adventure::Location::add_location sub add_thingy { my ( $parent, $thing ) = @_; my $name = ‘add_’ . $thing; my $package = qualify ucfirst(lc $thing), $parent; *{ qualify_to_ref $name => $package } = sub { my ($class, $name, $data ) = @_; $class->$type->{$name} = $package->new->init($name, $data ); };
  • 29. Summary Exercising objects is simple, repetitive. MJD’s “Red Flags”: don’t cut & paste. Replace hardwired loops with data-driven code. Object::Exercise standardizes the loops. Tests are declarative data.