The document discusses issues with the Test::More module for testing in Perl and proposes solutions. It notes that Test::More does not encourage writing tests based on specifications, does not structure tests well, and makes it hard to distinguish assertions. It recommends writing tests according to specifications rather than code, using structures like contexts and descriptions to organize tests, and printing output lines on a per-specification rather than per-assertion basis to improve readability. It also proposes functions like spec() and subtest() to help write more specification-based tests with Test::More.
Thoughts On Learning A New Programming LanguagePatricia Aas
How should we teach a new language to folks that already know how to program?
How do we use what we already know to leapfrog the learning process?
Based on my personal experience and snippets of natural language theory, we will try to explore the cheats and pitfalls when learning a new programming language, but also dig into how we can make it easier.
If you don’t test it, how do you know it works? Over the past few years, we have been compelled to write unit and integration tests for our applications--code that validates code--and it is these tests that change a one-off tool into a well-architected, robust, business-ready application. Yet, every new framework requires a new testing framework, so in this session, we will discuss testing frameworks for node.js. You will walk away with a solid understanding of how to write tests against your node.js applications and modules, leading to confidence that your work is business-ready.
A better version can be found at https://app.box.com/s/8zuk8yd4x9m7rbvinkb0xztz17x6xoqj
This is the slide for a presentation at Golang Melbourne meetup.
Secure Programming Practices in C++ (NDC Security 2018)Patricia Aas
This talk is for programmers wishing to feel more comfortable navigating the C++ landscape. We will explore the programming culture that has developed around the C++ language. Specifically, we will look at programming patterns that navigate around or through some of the dangerous parts of the C++ language. The goal is to build a set of programming practices based in the “smaller and cleaner language” inside C++. And by doing so, we will also build an awareness around code constructs that can potentially “blows your whole leg off”.
Thoughts On Learning A New Programming LanguagePatricia Aas
How should we teach a new language to folks that already know how to program?
How do we use what we already know to leapfrog the learning process?
Based on my personal experience and snippets of natural language theory, we will try to explore the cheats and pitfalls when learning a new programming language, but also dig into how we can make it easier.
If you don’t test it, how do you know it works? Over the past few years, we have been compelled to write unit and integration tests for our applications--code that validates code--and it is these tests that change a one-off tool into a well-architected, robust, business-ready application. Yet, every new framework requires a new testing framework, so in this session, we will discuss testing frameworks for node.js. You will walk away with a solid understanding of how to write tests against your node.js applications and modules, leading to confidence that your work is business-ready.
A better version can be found at https://app.box.com/s/8zuk8yd4x9m7rbvinkb0xztz17x6xoqj
This is the slide for a presentation at Golang Melbourne meetup.
Secure Programming Practices in C++ (NDC Security 2018)Patricia Aas
This talk is for programmers wishing to feel more comfortable navigating the C++ landscape. We will explore the programming culture that has developed around the C++ language. Specifically, we will look at programming patterns that navigate around or through some of the dangerous parts of the C++ language. The goal is to build a set of programming practices based in the “smaller and cleaner language” inside C++. And by doing so, we will also build an awareness around code constructs that can potentially “blows your whole leg off”.
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...Istanbul Tech Talks
Eric presents ProGuard - the open-source optimizer and obfuscator that is integrated in the Android SDK. ProGuard reduces the size of applications, improves their performance, and makes them more difficult to reverse-engineer. Eric presents some typical results on what to expect from ProGuard, discuss the latest developments and provide some background that should help mobile developers get the best out of ProGuard.
The Anatomy of an Exploit (NDC TechTown 2019)Patricia Aas
Security vulnerabilities and secure coding is often talked about in the abstract by programmers, but rarely understood. In this talk we will walk through simple exploit attempts, and finally a simple stack buffer overflow exploit, how it’s developed and how it’s used.
The goal is to try to get a feeling for the point of view of an "attacker", and to slowly start looking at exploitation as just another programming practice. We will mainly be looking at C and x86_64 assembly, so bring snacks.
C++ for Java Developers (JavaZone Academy 2018)Patricia Aas
Introduction to Modern C++ for programmers with a Java background. Maps key C++ concepts to Java concepts and dives into how C++ programmers deal with and think about memory. This intersection is interesting whether you are learning or teaching C++.
JavaScript ist eine sehr dynamische Sprache und verhält sich zudem je nach Browser unterschiedlich. Daher sind automatisierte Tests besonders wertvoll. Dieser Vortrag von Tobias Bosch und Stefan Scheidt (OPITZ CONSULTING) zeigt, wie Cross-Browser-Tests für JavaScript entwickelt werden können.
The latest emerging tools and frameworks allow us to write applications (and test them!) much more productively than ever before. This talk explores that concept through a whirlwind tour of numerous advanced testing techniques. A significant emphasis will be on the use of testing DSLs and the use of advanced scripting aproaches using the Groovy programming language (though the principals apply equally well with numerous recent innovative languages).
ITT 2014 - Eric Lafortune - ProGuard, Optimizer and Obfuscator in the Android...Istanbul Tech Talks
Eric presents ProGuard - the open-source optimizer and obfuscator that is integrated in the Android SDK. ProGuard reduces the size of applications, improves their performance, and makes them more difficult to reverse-engineer. Eric presents some typical results on what to expect from ProGuard, discuss the latest developments and provide some background that should help mobile developers get the best out of ProGuard.
The Anatomy of an Exploit (NDC TechTown 2019)Patricia Aas
Security vulnerabilities and secure coding is often talked about in the abstract by programmers, but rarely understood. In this talk we will walk through simple exploit attempts, and finally a simple stack buffer overflow exploit, how it’s developed and how it’s used.
The goal is to try to get a feeling for the point of view of an "attacker", and to slowly start looking at exploitation as just another programming practice. We will mainly be looking at C and x86_64 assembly, so bring snacks.
C++ for Java Developers (JavaZone Academy 2018)Patricia Aas
Introduction to Modern C++ for programmers with a Java background. Maps key C++ concepts to Java concepts and dives into how C++ programmers deal with and think about memory. This intersection is interesting whether you are learning or teaching C++.
JavaScript ist eine sehr dynamische Sprache und verhält sich zudem je nach Browser unterschiedlich. Daher sind automatisierte Tests besonders wertvoll. Dieser Vortrag von Tobias Bosch und Stefan Scheidt (OPITZ CONSULTING) zeigt, wie Cross-Browser-Tests für JavaScript entwickelt werden können.
The latest emerging tools and frameworks allow us to write applications (and test them!) much more productively than ever before. This talk explores that concept through a whirlwind tour of numerous advanced testing techniques. A significant emphasis will be on the use of testing DSLs and the use of advanced scripting aproaches using the Groovy programming language (though the principals apply equally well with numerous recent innovative languages).
Go 1.10 Release Party, featuring what's new in Go 1.10 and a few deep dives into how Go works.
Presented at the PDX Go Meetup on April 24th, 2018.
https://www.meetup.com/PDX-Go/events/248938586/
Why you should be using the shiny new C# 6.0 features now!Eric Phan
C# 6.0 will change the way you write C#. There are many language features that are so much more efficient you’ll wonder why they weren’t there since the beginning.
The $path to knowledge: What little it take to unit-test Perl.Workhorse Computing
Metadata-driven lazyness, Perl, and Jenkins provide a nice mix for automated testing. With Perl the only thing required to start testing is a files path, from there the possibilities are endless. Using Symbol's qualify_to_ref makes it easy to validate @EXPORT & @EXPORT_OK, knowing the path makes it easy to use "perl -wc" to get diagnostics.
The beautiful thing is all of it can be lazy... er, "automated". And repeatable. And simple.
Router is one of the most important feature or component in Web application framework,
ant it is also one of the performance bottlenecks of framework.
In this session, I'll show you how to make router much faster than ever.
Oktest - a new style testing library for Python -kwatch
Oktest is a new-style testing library for Python. It helps you to read & write tests very much. Oktest is available with (or without) standard 'unittest' module.
UiPath Test Automation using UiPath Test Suite series, part 3DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 3. In this session, we will cover desktop automation along with UI automation.
Topics covered:
UI automation Introduction,
UI automation Sample
Desktop automation flow
Pradeep Chinnala, Senior Consultant Automation Developer @WonderBotz and UiPath MVP
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
JMeter webinar - integration with InfluxDB and GrafanaRTTS
Watch this recorded webinar about real-time monitoring of application performance. See how to integrate Apache JMeter, the open-source leader in performance testing, with InfluxDB, the open-source time-series database, and Grafana, the open-source analytics and visualization application.
In this webinar, we will review the benefits of leveraging InfluxDB and Grafana when executing load tests and demonstrate how these tools are used to visualize performance metrics.
Length: 30 minutes
Session Overview
-------------------------------------------
During this webinar, we will cover the following topics while demonstrating the integrations of JMeter, InfluxDB and Grafana:
- What out-of-the-box solutions are available for real-time monitoring JMeter tests?
- What are the benefits of integrating InfluxDB and Grafana into the load testing stack?
- Which features are provided by Grafana?
- Demonstration of InfluxDB and Grafana using a practice web application
To view the webinar recording, go to:
https://www.rttsweb.com/jmeter-integration-webinar
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
A presentation about the usage and availability of Varnish on Kubernetes. This talk explores the capabilities of Varnish caching and shows how to use the Varnish Helm chart to deploy it to Kubernetes.
This presentation was delivered at K8SUG Singapore. See https://feryn.eu/presentations/accelerate-your-kubernetes-clusters-with-varnish-caching-k8sug-singapore-28-2024 for more details.
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Albert Hoitingh
In this session I delve into the encryption technology used in Microsoft 365 and Microsoft Purview. Including the concepts of Customer Key and Double Key Encryption.
State of ICS and IoT Cyber Threat Landscape Report 2024 previewPrayukth K V
The IoT and OT threat landscape report has been prepared by the Threat Research Team at Sectrio using data from Sectrio, cyber threat intelligence farming facilities spread across over 85 cities around the world. In addition, Sectrio also runs AI-based advanced threat and payload engagement facilities that serve as sinks to attract and engage sophisticated threat actors, and newer malware including new variants and latent threats that are at an earlier stage of development.
The latest edition of the OT/ICS and IoT security Threat Landscape Report 2024 also covers:
State of global ICS asset and network exposure
Sectoral targets and attacks as well as the cost of ransom
Global APT activity, AI usage, actor and tactic profiles, and implications
Rise in volumes of AI-powered cyberattacks
Major cyber events in 2024
Malware and malicious payload trends
Cyberattack types and targets
Vulnerability exploit attempts on CVEs
Attacks on counties – USA
Expansion of bot farms – how, where, and why
In-depth analysis of the cyber threat landscape across North America, South America, Europe, APAC, and the Middle East
Why are attacks on smart factories rising?
Cyber risk predictions
Axis of attacks – Europe
Systemic attacks in the Middle East
Download the full report from here:
https://sectrio.com/resources/ot-threat-landscape-reports/sectrio-releases-ot-ics-and-iot-security-threat-landscape-report-2024/
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
Sidekick Solutions uses Bonterra Impact Management (fka Social Solutions Apricot) and automation solutions to integrate data for business workflows.
We believe integration and automation are essential to user experience and the promise of efficient work through technology. Automation is the critical ingredient to realizing that full vision. We develop integration products and services for Bonterra Case Management software to support the deployment of automations for a variety of use cases.
This video focuses on the notifications, alerts, and approval requests using Slack for Bonterra Impact Management. The solutions covered in this webinar can also be deployed for Microsoft Teams.
Interested in deploying notification automations for Bonterra Impact Management? Contact us at sales@sidekicksolutionsllc.com to discuss next steps.
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf91mobiles
91mobiles recently conducted a Smart TV Buyer Insights Survey in which we asked over 3,000 respondents about the TV they own, aspects they look at on a new TV, and their TV buying preferences.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
1. YAPC::ASIA 2012
What is wrong
on Test::More?
Test::Moreが抱える問題点とその解決策
makoto kuwata <kwa@kuwata-lab.com>
http://www.kuwata-lab.com/
2012-09-27 (Fri)
copyright(c) 2012 kuwata-lab.com all rights reserved.
2. Agenda
✦ Testing without spec
仕様を書かずにテストしてる
✦ Not structured tests
テストが構造化されてない
✦ Needs test plan
事前にテストプラン (=テスト数) を必要とする
✦ No fixture feature
フィクスチャ機能がない
✦ Hard to distinguish assertions
どれがアサーションなのか分かりにくい
copyright(c) 2012 kuwata-lab.com all rights reserved.
4. Point
Write your test
according to spec,
not your code.
テストは、コードではなく仕様をもとに書け。
copyright(c) 2012 kuwata-lab.com all rights reserved.
5. Sample: Test::More (Perl)
use Test::More tests => 4;
is f(0), 0;
is f(1), 1;
is f(2), 1;
is f(3), 2;
copyright(c) 2012 kuwata-lab.com all rights reserved.
6. Sample: RSpec (Ruby)
describe 'f()'
it "calculates fibonacchi sequence" do
f(0).should == 0
f(1).should == 1
f(2).should == 1
f(3).should == 2
end
end
copyright(c) 2012 kuwata-lab.com all rights reserved.
7. Sample: unittest (Python)
import unittest
class FooTest(unittest.TestCase):
def test_calculates_fiboacchi_seq(self):
"""Calculates Fibonacchi sequence"""
self.assertEqual(0, f(0))
self.assertEqual(1, f(1))
self.assertEqual(1, f(2))
self.assertEqual(2, f(3))
copyright(c) 2012 kuwata-lab.com all rights reserved.
8. Goal of test
✦ Test::More:
Does that code run correctly?
そのコードは意図した通りに動くか?
✦ RSpec:
Does that code satisfy the spec?
そのコードは仕様を満たしているか?
copyright(c) 2012 kuwata-lab.com all rights reserved.
9. Difference between Test::More and RSpec
## Test::More
like $html, qr'<h3>Hello</h3>';
Higher-level information
より高水準の情報
## RSpec
it "contains section title" do
html.should =~ %r'<h3>Hello</h3>'
end
copyright(c) 2012 kuwata-lab.com all rights reserved.
10. Solution: spec()
https://gist.github.com/3797929
sub spec {
my ($text, $block) = @_;
$block->();
}
## usage
spec "page contains section title", sub {
ok(render() =~ qr`<h1>Hello</h1>`);
};
copyright(c) 2012 kuwata-lab.com all rights reserved.
11. Spec First
Step 1. Write specifications
spec "...specification1...";
spec "...specification2...";
#=> not ok 1 - ...spec... # TODO
#=> not ok 2 - ...spec... # TODO
Step 2. Add assertions according to spec
spec "...specification...", sub {
assertion1;
assertion2;
};
copyright(c) 2012 kuwata-lab.com all rights reserved.
12. Solution: spec()
https://gist.github.com/3797939
sub spec {
my ($text, $block) = @_;
return $block->() if $block;
TODO: {
local $TODO = ": not implemented yet";
ok(undef);
}
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
13. Meaning of output lines
As is - 'ok' when assertion passed, 'not ok' when
failed
アサーションが成功したらok、失敗したらnot ok
ok 1 - assertion1
not ok 2 - assertion2
To be - 'ok' when spec satisfied, 'not ok' when not
コードが仕様を満たしたらok、満たさなければnot ok
ok 1 - specification1
not ok 2 - specification2
copyright(c) 2012 kuwata-lab.com all rights reserved.
14. Spec : Assertion = 1 : N
✦A specification can contain some
assertions
1つの仕様に複数のアサーションを書いてよい
spec "returns pair of integer", sub {
is scalar(@$ret), 2;
like $ret->[0], qr/^d+$/;
like $ret->[1], qr/^d+$/;
};
copyright(c) 2012 kuwata-lab.com all rights reserved.
15. Spec : Assertion = 1 : N
As is Output lines per assertion
アサーションごとに出力行
ok 1
ok 2
ok 3
To be
ok 1 - returns pair of integer
Output lines per spec
仕様ごとに出力行
copyright(c) 2012 kuwata-lab.com all rights reserved.
16. Solution: OK()
https://gist.github.com/3797954
sub OK {
my ($expr) = @_;
unless ($expr) {
my ($pkg, $file, $lineno) = caller();
die "AssertionFailed"
." at $file line $lineno.n";
}
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
17. Solution: spec()
https://gist.github.com/3797954
my $spec = undef;
my $num = 0;
sub spec {
my ($text, $block) = @_;
$spec = $text;
$num++;
eval { $block->(); };
my $err = $@;
if (! $err) {
print "ok $num - $textn";
} else {
print "not ok $num - $textn";
$err =~ s/^/# /mg;
$err .= "n" if $err !~ /nz/;
print STDERR $err;
}
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
18. Conclusion of this section
✦ Write test based on spec, not on code
テストは、コードに対してではなく、仕様に対して書く
✦ 'Spec specified?' instead of 'Run correctly?'
「正しく動作するか?」ではなく「仕様を満たしているか?」
✦ Spec first, assertion second
仕様を先に書いて、そのあとにアサーションを書く
✦ Spec : Assertion = 1 : N
1つの仕様が複数のアサーションを含んでよい
✦ Output line per spec, not assertion
出力行のok / not okはアサーション単位ではなく仕様単位に出す
copyright(c) 2012 kuwata-lab.com all rights reserved.
20. Point
Test should have structure.
Because spec has structure.
テストには構造がある。なぜなら仕様に構造があるから。
copyright(c) 2012 kuwata-lab.com all rights reserved.
21. Sample: Specification document
クラス:Calendar
メソッド:isLeapYear(int year): boolean
動作詳細:
・100で割り切れる場合、
・400で割り切れる場合はtrueを返す
・それ以外はfalseを返す
・4で割り切れる場合はtrueを返す
・それ以外はfalseを返す
copyright(c) 2012 kuwata-lab.com all rights reserved.
22. Test code as spec document
Is your test code available
as spec document?
そのコードは仕様書としてほんとに利用できるの?
copyright(c) 2012 kuwata-lab.com all rights reserved.
23. Sample: Test::More
use Test::More tests => 2;
use Foo;
$foo = Foo->new();
is(Foo->new()->meth1(), 11);
is(Foo->new()->meth2(), 12);
copyright(c) 2012 kuwata-lab.com all rights reserved.
24. Sample: RSpec
Test target (class, method, ...)
require 'rspec' テスト対象 (クラス、メソッド、…)
describe Foo do
describe '#bar()' do
context 'when arg is provided' do
it "returns length" do
Foo.new.methd1([0,1,2]).should == 3
Foo.new.methd1([]).should == 0
end
end
end
end
copyright(c) 2012 kuwata-lab.com all rights reserved.
25. Sample: RSpec
Test condition or situation
require 'rspec' 条件や状況
describe Foo do
describe '#bar()' do
context 'when arg is provided' do
it "returns length" do
Foo.new.methd1([0,1,2]).should == 3
Foo.new.methd1([]).should == 0
end
end
end
end
copyright(c) 2012 kuwata-lab.com all rights reserved.
26. Sample: RSpec
require 'rspec'
describe Foo do
describe '#bar()' do
context 'when arg is provided' do
it "returns length" do
Foo.new.methd1([0,1,2]).should == 3
Foo.new.methd1([]).should == 0
end
end
end Specification
仕様
end
copyright(c) 2012 kuwata-lab.com all rights reserved.
27. Sample: unittest (Python)
import unittest
class FooTest(unitteset.TestCase):
def test_bar_1(self):
"""returns length of arg passed"""
self.assertequal(3, Foo().bar([1,2,3]))
def test_bar_2(self):
"""returns 0 when arg is not passed"""
self.assertEqual(0, Foo().bar())
copyright(c) 2012 kuwata-lab.com all rights reserved.
28. Sample: Test::Unit2 (Ruby)
require 'test/unit'
require 'foo'
class FooTest < Test::Unit::TestCase
class MethTest < self
def test_returns_length_of_arg
n = Foo.new.bar([1,2,3])
assert_equal 3, n
end
end
end
ref: http://www.clear-code.com/blog/2012/4/25.html
copyright(c) 2012 kuwata-lab.com all rights reserved.
29. Sample: subtest() (Test::More)
use Test::More tests=>1;
subtest "package Foo", sub {
plan tests=>1;
subtest "sub bar()", sub {
plan tests=>2;
ok (1+1 == 2);
ok (1-1 == 0);
};
};
copyright(c) 2012 kuwata-lab.com all rights reserved.
30. Sample: subtest() (Test::More)
$ perl homhom.t
1..1
1..1
1..2
ok 1
ok 2
ok 1 - sub bar()
ok 1 - package Foo
copyright(c) 2012 kuwata-lab.com all rights reserved.
31. Sample: subtest() (Test::More)
$ perl homhom.t
1..1
1..1
1..2
ok 1
ok 2
ok 1 - sub bar()
ok 1 - package Foo
copyright(c) 2012 kuwata-lab.com all rights reserved.
32. Sample: subtest() (Test::More)
$ perl homhom.t
1..1
1..1
1..2
ok 1
ok 2
ok 1 - sub bar()
ok 1 - package Foo
copyright(c) 2012 kuwata-lab.com all rights reserved.
33. Solution: subtest() alternatives
Test target
テスト対象
print "1..2n";
topic 'package Foo', sub {
topic 'sub meth1()', sub {
case_when 'arg is passed', sub {
spec "1+1 should be 2", sub {
OK(1+1 == 2);
};
spec "1-1 should be 0", sub {
OK(1-1 == 0);
};
}; Condition or situation
}; 条件や状況
};
copyright(c) 2012 kuwata-lab.com all rights reserved.
34. Solution: subtest() alternatives
$ perl homhom.t
1..2
# * package Foo
# * sub meth1()
# - when arg is passed
ok 1 - 1+1 should be 2
ok 2 - 1-1 should be 0
copyright(c) 2012 kuwata-lab.com all rights reserved.
35. Solution: subtest() alternatives
https://gist.github.com/3797976
my $depth = 0;
sub topic {
my ($name, $block) = @_;
my $indent = ' ' x $depth;
print "# $indent* $namen";
$depth++;
$block->();
$depth--;
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
36. Solution: subtest() alternatives
https://gist.github.com/3797976
my $depth = 0;
sub case_when {
my ($condition, $block) = @_;
my $indent = ' ' x $depth;
print "# $indent- $conditionn";
$depth++;
$block->();
$depth--;
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
37. Conclution of this section
✦ Testhas structure, because spec has
structure.
テストには構造がある。なぜなら仕様に構造があるから。
✦ xUnit
focuses on test automation,
RSpec focuses on test structure.
xUnitは自動化のための道具、RSpecは構造化のための道具
✦ Output
of subtest() suck.
Define your own subtest alternatives.
subtest()は出力が残念すぎる。自前関数お勧め。
copyright(c) 2012 kuwata-lab.com all rights reserved.
38. Section 3:
Needs test plan
事前にテストプラン (=テスト数) を必要とする
copyright(c) 2012 kuwata-lab.com all rights reserved.
39. Sample: Test::More
use Test::More tests=>2;
is(1+1, 2);
is(1-1, 0);
$ perl homhom.t
1..2
ok 1
ok 2
copyright(c) 2012 kuwata-lab.com all rights reserved.
40. Sample: subtest()
use Test::More tests=>1;
subtest 'package Foo', sub {
plan tests=>1;
subtest 'sub meth()', sub {
plan test2=>1;
is(1+1, 2);
is(1-1, 0);
};
};
copyright(c) 2012 kuwata-lab.com all rights reserved.
41. Pros of test plan
✦ Detect unexpected test finishing
テストの異常終了が検知できる
• Compare number of ('ok' + 'not ok') with test
plan
出力されたokやnot okの数と、 宣言されたテスト個数とを比較
✦ Necessary to report test progress
テスト実行時に進行状況を知るのに必要
• Especially for 'prove' command
特にproveコマンドで
copyright(c) 2012 kuwata-lab.com all rights reserved.
42. Cons of test plan
✦ Too messy to keep currect value
正しい値に更新し続けるのが面倒すぎる
• Update test plan when you add assertions
assertion関数を追加したら忘れずに更新
• back to top when you add at the end of file
ファイルの末尾にテストを追加したら、先頭に戻ってテスト数
を更新
copyright(c) 2012 kuwata-lab.com all rights reserved.
43. Sample: done_testing()
use Test::More tests=>2;
is(1+1, 2);
is(1-1, 0);
done_testing();
$ perl homhom.t
ok 1
ok 2
1..2
copyright(c) 2012 kuwata-lab.com all rights reserved.
44. done_testing() and subtest()
use Test::More tests=>1;
subtest "package Foo", sub {
subtest "sub meth1()", sub {
ok (1+1 == 2);
ok (1-1 == 0);
done_testing();
};
done_testing();
};
done_testing();
(No need to call done_testing() in subtest() since Test::More 0.95_01)
copyright(c) 2012 kuwata-lab.com all rights reserved.
45. Solution: subtest() alternatives
$ perl homhom.pl
ok 1
ok 2
1..2
ok 1 - sub meth1()
1..1
ok 1 - package Foo
1..1
copyright(c) 2012 kuwata-lab.com all rights reserved.
46. Pros of done_testing()
✦ No need to speicfy test plan!
テスト数を指定しなくていい!
copyright(c) 2012 kuwata-lab.com all rights reserved.
47. Cons of done_testing()
✦ Need to expand TAP spec
TAP仕様に拡張が必要
• Simplicity of TAP has gone
もはやTAPの簡易性は損なわれた
✦ 'Prove' prints '?' as number of tests
proveコマンドで全体のテスト数が「?」に
• Degeneration of interface
インターフェースとしては退化
copyright(c) 2012 kuwata-lab.com all rights reserved.
48. Off Topic: Doubt about TAP
✦ If TAP accepts test plan after running tests,
テスト数がわかるのがテスト終了後でいいなら
• 'End of test' indicatior is necessary for TAP, but
test plan is not, is it?
テストの終わりが分かる何かがあればテスト数いらなくね?
• Index number of test is not necessary, is it?
そもそも ok や not ok に通し番号いらなくね?
ok 1 # ..spec..
ok 2 # ..spec..
<<TEST END>>
copyright(c) 2012 kuwata-lab.com all rights reserved.
49. The root cause of problem
✦ Impossibleto count number of tests
before running tests
テスト数を事前に数えられない
✦ To be
あるべき姿
• Step1. Count and print number of tests
テスト数を数えて出力
• Step2. Run tests
テストを実行
copyright(c) 2012 kuwata-lab.com all rights reserved.
50. Solution: Intermediate data structure
As is:
is 1+1, 2; ok 1
is 1-1, 0; ok 2
1..2
To be:
topic
is 1+1, 2; topic 1..2
is 1-1, 0; ok 1
spec ok 2
spec
Easy to
count tests
copyright(c) 2012 kuwata-lab.com all rights reserved.
51. Cons of intermediate data structure
✦ Easyto count and filter tests before
running tests
テスト実行前にテストを数えたりフィルタするのが簡単にできる
✦ No need to extend TAP specification
TAPの仕様を拡張しなくてよい
• No more done_testing()
done_testing()なんていらない
• No more nesting like subtest()
subtest()のような入れ子対応はいらない
copyright(c) 2012 kuwata-lab.com all rights reserved.
52. Sample: xUnit
class FooTest(TestCase):
def test1(self): ...
def test2(self): ...
## build intermediate data structure
suite = TestSuite()
suite.add(FooTest('test1'))
suite.add(FooTest('test2'))
## run tests
TestRunner().run(suite)
copyright(c) 2012 kuwata-lab.com all rights reserved.
53. Solution: topic() and spec()
https://gist.github.com/3798000
topic 'class Foo', sub {
topic 'sub meth1()', sub {
case_when "arg is given", sub {
spec "1+1 should be 2", sub {
OK(1+1 == 2);
};
}; Change to build tree
};
};
Traverse tree
run_all();
copyright(c) 2012 kuwata-lab.com all rights reserved.
54. Solution: topic()
https://gist.github.com/3798000
my $NODES = [];
sub topic {
my ($name, $block) = @_;
my $node = {name=>$name, prefix=>'*',
children=>[]};
push @$NODES, $node;
my $bkup = $NODES;
$NODES = $node->{children};
$block->();
$NODES = $bkup;
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
55. Solution: spec()
https://gist.github.com/3798000
my $NODES = [];
sub spec {
my ($text, $block) = @_;
push @$NODES, [$text, $block];
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
56. Solution: _count_specs()
https://gist.github.com/3798000
sub _count_specs {
my ($nodes) = @_;
my $n = 0;
for (@$nodes) {
if (ref($_) eq 'HASH') { # topic
$n += _count_specs($_->{children});
} elsif (ref($_) eq 'ARRAY') { # spec
$n += 1;
}
}
return $n;
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
57. Solution: run_all()
https://gist.github.com/3798000
sub run_all {
print "1..", _count_specs($NODES), "n";
_run_all($NODES, 0, 0);
}
sub _run_all {
my ($nodes, $depth, $num) = @_;
my $indent = ' ' x $depth;
for my $x (@$nodes) {
if (ref($x) eq 'HASH') { # topic
print "# $indent$x->{prefix} $x->{name}n";
$num = _run_all($x->{children}, $depth + 1, $num);
}
elsif (ref($x) eq 'ARRAY') { # spec
my ($text, $block) = @$x;
$num++;
_run_spec($text, $num, $block);
}
}
return $num;
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
58. Conclustion in this seciton
✦ Don't count tests manually. Use computer.
テスト数を手動で数えるのはやめてコンピュータにさせよう
✦ Noneed to expand TAP specification.
Both done_testing() and subtest() are
wrong.
TAPの仕様拡張は不必要。done_testing()もsubtest()も間違い
✦ Intermediate data structure solves the
problem.
テストを表す中間データ構造を作れば万事解決
copyright(c) 2012 kuwata-lab.com all rights reserved.
59. Section 4:
No fixture feature
フィクスチャ機能がない
copyright(c) 2012 kuwata-lab.com all rights reserved.
60. What is fixture?
"A test fixture (also known as a test context) is the
set of preconditions or state needed to run a test.
The developer should set up a known good state
before the tests, and return to the original state
after the tests."
http://en.wikipedia.org/wiki/XUnit
"テストを実行、成功させるために必要な状態や前提条件の集合
を、フィクスチャと呼ぶ。これらはテストコンテキストとも呼
ばれる。開発者はテストの実行前にテストに適した状態を整
え、テスト実行後に元の状態を復元することが望ましい。"
http://ja.wikipedia.org/wiki/XUnit
copyright(c) 2012 kuwata-lab.com all rights reserved.
62. Fault of setUp/tearDown
All tests in a class must share a setUp/tearDown.
sub setUp { my ($self) = @_;
$self->man = User->new(gender=>'M');
$self->woman = User->new(gender=>'W');
}
sub test1 { my ($self) = @_;
my $user = $self->man;
...
}
sub test2 { my ($self) = @_;
my $user = $self->woman;
...
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
63. Fault of setUp/tearDown
Separate TestCase class?
package FooTestCase;
sub setUp { ... }
sub testFoo { ... }
package BarTestCase;
sub setUp { ... }
sub testBar { ... }
No. Test structure should follow specification
reason, not fixture reason.
copyright(c) 2012 kuwata-lab.com all rights reserved.
64. Another approach on fixture
Define fixture method for each test data.
sub fx_man {
return User->new(gender=>'M'); }
sub fx_woman {
return User->new(gender=>'W'); }
spec "test for man", sub {
OK(fx_man()->{gender} eq 'M'); }
spec "test for woman", sub {
OK(fx_woman()->{gender} eq 'W'); }
More flexible than setUp/tearDown
copyright(c) 2012 kuwata-lab.com all rights reserved.
65. Cons of the approach
spec "returns length of file", sub {
my $file = fx_file("homhom");
OK(file_length($file) == 6);
unlink($file);
};
Troublesome task to do teardown
for each fixture data
fixtureごとに忘れずに解放処理を行うのは面倒
copyright(c) 2012 kuwata-lab.com all rights reserved.
66. Solution: at_end()
sub fx_file {
my ($content) = (@_);
$file = "test-".rand().".txt";
write_file($file, $content);
at_end { unlink($file); };
return $file;
}
Register task called at end of test
テストの終わりに実行される処理を登録する
copyright(c) 2012 kuwata-lab.com all rights reserved.
67. Solution: at_end()
spec "returns length of file", sub {
my $file = fx_file("homhom");
OK(file_length($file) == 6);
unlink $file;
};
No need to teardown for each test
テストごとの終了処理を書く必要がなくなる
copyright(c) 2012 kuwata-lab.com all rights reserved.
68. Solution: at_end()
https://gist.github.com/3798046
our @_CLOSURES = ();
sub at_end(&) {
my ($closure) = @_;
push @_CLOSURES, $closure;
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
69. Solution: _run_spec()
https://gist.github.com/3798046
sub _run_spec {
my ($text, $num, $closure) = @_;
eval { $closure->(); };
my $s = $@ ? "ok" : "not ok";
print "$s $num - $textn";
my $@ = undef;
for my $clos (reverse(@_CLOSURES)) {
$clos->();
}
@_CLOSURES = ();
}
copyright(c) 2012 kuwata-lab.com all rights reserved.
70. Conclusion in this section
✦ No fixture feature in Test::More
Test::Moreにはfixture機能がない
✦ SetUp()/tearDown() are not so good
setUp()/tearDown()も良くはない
✦ Use end_at() which registers teardown
task in setup
作成時に解放処理を登録できるat_end()が便利
copyright(c) 2012 kuwata-lab.com all rights reserved.
71. Section 5:
Hard to distinguish assertions
どれがアサーションなのか分かりにくい
copyright(c) 2012 kuwata-lab.com all rights reserved.
72. Assertions in xUnit
Consistent naming rule for assertion methods.
アサーションメソッドに一貫した命名規則がある
Easy to distinguish assertions in test code
テストコード中でアサーションを見分けるのが簡単
assertTrue()
assertEqual()
assertMatch()
assertSet()
...
copyright(c) 2012 kuwata-lab.com all rights reserved.
73. Assertions in Test::More
No naming rule for assertion functions.
アサーションメソッドに一貫した命名規則がない
Hard to distinguish assertions in test code
テストコード中でアサーションを見分けるのが困難
ok()
is()
like()
eq_set()
cmp_ok()
...
copyright(c) 2012 kuwata-lab.com all rights reserved.
74. Solution: AssertionObject class
https://gist.github.com/3798075
Collect assertion functions in a class.
アサーション関数を1つのクラスに集約
package AssertionObject;
## assertion methods
sub num_eq { ... }
sub str_eq { ... }
sub match { ... }
...
copyright(c) 2012 kuwata-lab.com all rights reserved.
75. Solution: OK()
https://gist.github.com/3798075
Change OK() which returns AssertionObject.
AssertionObjectインスタンスを返すようにOK()を変更
sub OK {
my ($actual) = @_;
return AssertionObject->new($actual);
}
Easy to distinguish assertions
## usage どれがアサーションかすぐ分かる
OK (1+1)->num_eq(2);
OK ("a")->str_eq("a");
OK ("9")->match(qr/^d+/);
copyright(c) 2012 kuwata-lab.com all rights reserved.
76. Solution: Operator overload
https://gist.github.com/3798075
package AssertionObject;
use overload
'==' => &num_eq,
'eq' => &str_eq;
package main;
OK (1+1) == 2; // same as num_eq()
OK ("a") eq "a"; // same as str_eq()
Shortcut to assertion methods
アサーションメソッドを簡単呼び出し
copyright(c) 2012 kuwata-lab.com all rights reserved.
77. ok() vs. OK()
ok(2 == 1);
not ok 1
# Failed test at homhom.t line 4.
OK(2) == 1;
not ok 1
# AssertionFailed at homhom.t line 4.
# $actual == $expected: failed
# actual: 2
# expected: 1
copyright(c) 2012 kuwata-lab.com all rights reserved.
78. is() vs. OK()
is() :
is("1.0", 1.0); #=> not ok
OK() :
OK ("1.0") eq 1.0; #=> not ok
OK ("1.0") == 1.0; #=> ok
You can choose 'eq' or '=='.
文字列演算子と数値演算子を選べる
copyright(c) 2012 kuwata-lab.com all rights reserved.
79. Test::More vs. OK()
Test::More OK()
ok(1+1 == 2); OK (1+1) == 2;
isnt(1+1, 0); OK (1+1) != 0;
cmp_ok(1+1, '>=', 1); OK (1+1) >= 1;
Consistent usage
一貫した使い方
copyright(c) 2012 kuwata-lab.com all rights reserved.
80. Conclusion in this section
✦ Noconsistent naming rule of assertion
functions in Test::Unit
Test::Moreにはアサーション関数に一貫した命名規則がない
✦ Hard to distinguish assertions in test
テストコード中でどれがアサーションか見分けるのが困難
✦ Solution:
AssertionObject class and
operator overload
解決策:AssertionObjectクラスと演算子オーバーロード
copyright(c) 2012 kuwata-lab.com all rights reserved.
82. Oktest.pm - a new style testing library
http://search.cpan.org/~kwatch/Oktest/lib/Oktest.pm
use strict;
use warnings;
no warnings 'void'; # RECOMMENDED!
use Oktest;
topic "ClassName", sub {
topic "method_name()", sub {
spec "...detail...", sub {
OK (1+1) == 2;
OK ('a' x 3) eq 'aaa';
};
};
};
Oktest::main() if $0 eq __FILE__;
1;
copyright(c) 2012 kuwata-lab.com all rights reserved.