NAME

Test::YAFT::Introduction - Introduction to Test::YAFT

DESCRIPTION

Test::YAFT is manifestation of (my) opinion that tests should be so easy to read and understand that they can (and should) act as entrypoint into your project for newbies.

BASIC USAGE

Basic test structure doesn't differ much from usage of Test::Simple / Test::More. Main differences are:

mandatory test message

Test message is mandatory and is always a first argument of every assert function.

Every other argument is provided using named argument approach.

Test::Deep comparison

Every comparison uses Test::Deep

HOW TO USE IT

it assert

Basic assert Test::YAFT provides is an it. Naming expects that you have either subtests describing your testing intention or one behaviour per test file, so it can be bounded with something from your domain.

subtest "Person" => sub {
	it "should have method foo()"
		=> got    => defined &{ Person->can ('foo') }
		=> expect => expect_true
		;
};

Computed got

it can compute got value

subtest "method birthday()" => sub {
	it "should increment person's age"
		=> got { $person->new (age => 41)->birthday; $person->age }
		=> expect => 42
		;
}

When using computed got approach Test::YAFT always executes given block in eval and verifies its status, so it fails with "expected to live / die" first.

expect code to die, if throws parameter exists
expect code to live otherwise
subtest "method birthday()" => sub {
	it "should increment person's age"
		=> got { $person->new (age => 41)->birthday; $person->age }
		=> expect => 42
		;

	it "should throw an exception when called too fast"
		=> got { $person->new (age => 41)->birthday->birthday; $person->age }
		=> throws => expect_re (qr/Person cannot be born twice a day/)
		;
}

Shared got computation (with arguments)

Often there are test scenarios when you share computation of got value but with different arguments for each assert.

Test::YAFT provides simple tool for that - act { } block

subtest "resource /countries/:continent provides alphabetical sorted list countries on the continent" => sub {
	act { GET "/countries/$_[0]" } 'continent';

	it "should list North America continental countries"
		=> with_continent => 'north-america'
		=> expect         =>
			& expect_http_success
			& expect_json_content_type
			& expect_json_content {
				countries => [
					'Canada',
					'Mexico',
					'USA',
				]
			}
		;

	it "should list Australia continental countries"
		=> with_continent => 'australia'
		=> expect         =>
			& expect_http_success
			& expect_json_content_type
			& expect_json_content {
				countries => [
					'Australia',
				]
			}
		;

	it "should list no country in Antarctica"
		=> with_continent => 'antarctica'
		=> expect         =>
			& expect_http_success
			& expect_json_content_type
			& expect_json_content {
				countries => [
				]
			}
		;
};

Arrange {} block

act {} block dependencies can be provided via similar arrange {} block.

it "should list no country in Antarctica"
	=> arrange { continent => 'antarctica' }
	=> expect         =>
		& expect_http_success
		& expect_json_content_type
		& expect_json_content {
			countries => [
			]
		}
	;

Difference is that arrange {} block is executed inside context of it. There can be multiple arrange blocks, executed in order of definition. Each block should return <singleton = value>> pairs, one singleton can be arranged only once.

AUTHOR

Branislav Zahradník <barney@cpan.org>

COPYRIGHT AND LICENCE

This file is part of Test::YAFT distribution.