From fe68d37bcdf33bd4fc06aa32b338ed5eb3e1278e Mon Sep 17 00:00:00 2001 From: Olaf Alders Date: Thu, 14 Dec 2023 15:21:44 -0500 Subject: [PATCH 1/3] 2023-12-15 and 2023-12-16 --- .../the-magical-test2-suite.pod => articles/2023-12-15.pod} | 0 .../2023-12-16.pod} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename 2023/{incoming/the-magical-test2-suite.pod => articles/2023-12-15.pod} (100%) rename 2023/{incoming/the-magical-test2-suite-part-2.pod => articles/2023-12-16.pod} (100%) diff --git a/2023/incoming/the-magical-test2-suite.pod b/2023/articles/2023-12-15.pod similarity index 100% rename from 2023/incoming/the-magical-test2-suite.pod rename to 2023/articles/2023-12-15.pod diff --git a/2023/incoming/the-magical-test2-suite-part-2.pod b/2023/articles/2023-12-16.pod similarity index 100% rename from 2023/incoming/the-magical-test2-suite-part-2.pod rename to 2023/articles/2023-12-16.pod From 58de26d61f2ca0625805d4064fe1c5fdf4de41fe Mon Sep 17 00:00:00 2001 From: Olaf Alders Date: Thu, 14 Dec 2023 15:25:18 -0500 Subject: [PATCH 2/3] Requote articles --- 2023/articles/2023-12-15.pod | 10 +++++----- 2023/articles/2023-12-16.pod | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/2023/articles/2023-12-15.pod b/2023/articles/2023-12-15.pod index e1ce6478e..f828e6500 100644 --- a/2023/articles/2023-12-15.pod +++ b/2023/articles/2023-12-15.pod @@ -10,7 +10,7 @@ But writing good tests can sometimes be a coal in the stocking. Some things are Well, not anymore. This year we updated all our test code to use the magical L. A single distribution that updates and replaces not just Test::More, but many other testing modules. And the best part? It will be a core distribution in Perl 5.40 onwards! Talk about a Christmas Miracle <3 -The basics work pretty much like Test::More, so if you’re used to it you’ll feel right at home. In fact, if you’re not doing anything fancy you can probably replace “C<< use Test::More >>” with “C<< use Test2::V0 >>” and everything will work just fine. Check it out: +The basics work pretty much like Test::More, so if you’re used to it you’ll feel right at home. In fact, if you’re not doing anything fancy you can probably replace "C<< use Test::More >>" with "C<< use Test2::V0 >>" and everything will work just fine. Check it out: use Test2::V0; @@ -36,7 +36,7 @@ The basics work pretty much like Test::More, so if you’re used to it you’ll like $xmas->carol, qr/Merry/, ‘found the proper lyrics’; } - done_testing; # you can also “plan N;” if you prefer to count your tests. + done_testing; # you can also "plan N;" if you prefer to count your tests. But you’ll also get some nice cranberry sauce right out of the box. For starters, C and C are on by default (and don’t worry, @@ -54,10 +54,10 @@ can write them as: and all that extra output will be printed only if the test fails. Ho! Ho! Ho! -=head2 The all-powerful “is” and “like” +=head2 The all-powerful "is" and "like" This is straight out my favorite feature. You may have noticed I did not -include “C” on the list of compatibility with Test::More. +include "C" on the list of compatibility with Test::More. Well, that’s because there is no need for it. That’s right! If the variable you’re testing is a data structure, you can simply use C and it will do a deep check, failing if values don’t match or if anything is missing: @@ -122,7 +122,7 @@ If that wasn’t impressive enough, here are some extra nice ways to make your t =head2 Test if something warns or dies / raises an exception like dies { … }, qr/some error/, ‘got expected exception from block’; - ok lives { … }, ‘code lived!’, “oh, noes! Died with error ‘$@’”; + ok lives { … }, ‘code lived!’, "oh, noes! Died with error ‘$@’"; ok warns { … }, ‘at least one warning was issued in the block’; is warns { … }, 2, ‘got the right number of warnings in block’; diff --git a/2023/articles/2023-12-16.pod b/2023/articles/2023-12-16.pod index d76f06dcc..3a0e12e28 100644 --- a/2023/articles/2023-12-16.pod +++ b/2023/articles/2023-12-16.pod @@ -43,7 +43,7 @@ When you need to test chained calls, you can always nest your mocks(): is $obj->happy->holidays->everyone, 'Ho! Ho! Ho!', 'chained mocks'; -I<“But Santa”>, you may ask, I<< “What about when the class is instantiated and used somewhere inside the code I want to test? How can I use mocks to add or override methods to something out of my hands?” >> No worries! Just expand your mock definition for more control: +I<"But Santa">, you may ask, I<< "What about when the class is instantiated and used somewhere inside the code I want to test? How can I use mocks to add or override methods to something out of my hands?" >> No worries! Just expand your mock definition for more control: my $mock_meta = mock 'Some::Class' => ( track => true, @@ -56,9 +56,9 @@ I<“But Santa”>, you may ask, I<< “What about when the class is instantiate ], ); -And now, as long as C<$mock_meta> exists, any instances of “C” will have the mocked behavior. To restore them back to the original, simply undefine that C<$mock_meta> variable or call C<< $mock_meta->reset_all() >>. +And now, as long as C<$mock_meta> exists, any instances of "C" will have the mocked behavior. To restore them back to the original, simply undefine that C<$mock_meta> variable or call C<< $mock_meta->reset_all() >>. -One thing you may have noticed in the example above is the “C<< track => true >>”. That means C<$mock_meta> will contain a lot of information ready for you to inspect regarding how many times any given method was called, and which arguments were used. This is particularly important to check if the code you’re testing is properly invoking the mocked class. +One thing you may have noticed in the example above is the "C<< track => true >>". That means C<$mock_meta> will contain a lot of information ready for you to inspect regarding how many times any given method was called, and which arguments were used. This is particularly important to check if the code you’re testing is properly invoking the mocked class. test_something_that_uses_my_mocked_class(); is( @@ -70,7 +70,7 @@ One thing you may have noticed in the example above is the “C<< track => true like( $mock_meta->sub_tracking->{some_method}[0]{args}, [ qr(), ‘arg1’, qr(arg2) ], - 'testing call arguments for method “some_method”' + 'testing call arguments for method "some_method"' ); $mock_meta->clear_sub_tracking(); # so we can go again in isolation From 03eae65ecb9a94ceb60d9f7dbba03906d90694d0 Mon Sep 17 00:00:00 2001 From: Olaf Alders Date: Thu, 14 Dec 2023 15:36:12 -0500 Subject: [PATCH 3/3] Add syntax highlighting to articles --- 2023/articles/2023-12-15.pod | 10 ++++++++++ 2023/articles/2023-12-16.pod | 12 ++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/2023/articles/2023-12-15.pod b/2023/articles/2023-12-15.pod index f828e6500..c5b7ee092 100644 --- a/2023/articles/2023-12-15.pod +++ b/2023/articles/2023-12-15.pod @@ -12,6 +12,7 @@ Well, not anymore. This year we updated all our test code to use the magical L>" with "C<< use Test2::V0 >>" and everything will work just fine. Check it out: + #!vim perl use Test2::V0; use Acme::Christmas; @@ -46,6 +47,7 @@ Now you can! Test2::V0’s C, C, C and most other test functions support extra arguments I, so you can write them as: + #!vim perl ok $xmas->ready, "test if christmas is ready" => "hmm... this was not supposed to fail. Let's see..." . " the tree is " . $xmas->tree @@ -62,6 +64,7 @@ Well, that’s because there is no need for it. That’s right! If the variable you’re testing is a data structure, you can simply use C and it will do a deep check, failing if values don’t match or if anything is missing: + #!vim perl is $recipe, { name => 'Fruitcake', ingredients => { @@ -78,6 +81,7 @@ It even lets you mix and match between exact values (by passing a string or a number) and values that match a regular expression (by providing the regexp). + #!vim perl like $recipe, { name => qr(cake)i, # must contain ‘cake’ (case insensitive) ingredients => { @@ -95,6 +99,7 @@ make sure it has no key called ‘microwave’. To do all that, we just write a very simple definition of our partial hash containing only the bits we care about: + #!vim perl # import everything we use in this test # (the :DEFAULT label is to ensure all regular symbols are also imported) use Test2::V0 qw( :DEFAULT hash field bag item etc L DNE ); @@ -114,6 +119,7 @@ If that wasn’t impressive enough, here are some extra nice ways to make your t =head2 Test if loading a module imports (or doesn’t import) a function or a variable: + #!vim perl use Some::Module; imported_ok 'mysub', '$myvar', '@myothervar'; not_imported_ok 'othersub', '$othervar'; @@ -121,6 +127,7 @@ If that wasn’t impressive enough, here are some extra nice ways to make your t =head2 Test if something warns or dies / raises an exception + #!vim perl like dies { … }, qr/some error/, ‘got expected exception from block’; ok lives { … }, ‘code lived!’, "oh, noes! Died with error ‘$@’"; @@ -136,16 +143,19 @@ If that wasn’t impressive enough, here are some extra nice ways to make your t If you add this to the beginning of your test file, it will die and stop testing that file as soon as any test on that file fails: + #!vim perl use Test2::Plugin::DieOnFail; If you’re running a bunch of different test files, it will not stop testing altogether, just that particular file. To truly bail out of all testing as soon as any test on a file fails, do this instead: + #!vim perl use Test2::Plugin::BailOnFail; If you just want to bail on a single test in the file, use "C<< ... or bail_out($reason) >>" after the test. =head2 Skip tests unless we have a specific perl or module version available: + #!vim perl # skip all tests in file unless perl is v5.38 or greater: use Test2::Require::Perl 'v5.38'; diff --git a/2023/articles/2023-12-16.pod b/2023/articles/2023-12-16.pod index 3a0e12e28..f0e954737 100644 --- a/2023/articles/2023-12-16.pod +++ b/2023/articles/2023-12-16.pod @@ -8,7 +8,7 @@ Greetings, festive readers! Santa Claus here, ready to share yet another behind-the-scenes look at how we keep Christmas joyfully on track with the Magical Test2 Suite, soon to be a core test library in Perl 5.40 onwards. -If you haven't read part 1, it's a real treat! +If you haven't read L, it's a real treat! Just like the tinsel on your tree, mocks add that extra sparkle to our unit tests. Mocks can help us simulate certain behaviors, creating a @@ -21,18 +21,21 @@ And with the Test 2 Suite, this has never been easier! For starters, let’s say you want to create an object that will be passively called by whatever it is you’re testing: + #!vim perl use Test2::V0; my $obj = mock; Now, C<$obj> is a dud that will accept any method calls and return C. What about if you want it to return something specific? + #!vim perl my $obj = mock { merry => 'christmas!' }; is $obj->merry, 'christmas!', 'my mock works'; When you need to test chained calls, you can always nest your mocks(): + #!vim perl my $obj = mock { happy => mock { holidays => mock { @@ -45,6 +48,7 @@ When you need to test chained calls, you can always nest your mocks(): I<"But Santa">, you may ask, I<< "What about when the class is instantiated and used somewhere inside the code I want to test? How can I use mocks to add or override methods to something out of my hands?" >> No worries! Just expand your mock definition for more control: + #!vim perl my $mock_meta = mock 'Some::Class' => ( track => true, override => [ @@ -60,6 +64,7 @@ And now, as long as C<$mock_meta> exists, any instances of "C" will One thing you may have noticed in the example above is the "C<< track => true >>". That means C<$mock_meta> will contain a lot of information ready for you to inspect regarding how many times any given method was called, and which arguments were used. This is particularly important to check if the code you’re testing is properly invoking the mocked class. + #!vim perl test_something_that_uses_my_mocked_class(); is( $mock_meta->sub_tracking->{some_method}->@*, @@ -78,7 +83,8 @@ One thing you may have noticed in the example above is the "C<< track => true >> Note that to get the mock metadata from a given variable holding an object, you can also do: - my ($mock_meta) = mocked $actual_obj; + #!vim perl + my ($mock_meta) = mocked $actual_obj; =head2 Mocking the Christmas Wishlist Database @@ -87,6 +93,7 @@ For a real world example, let's see how the elves use Test2 Suite's mocking features to test our gift delivery system. The code looks roughly like this: + #!vim perl sub deliver_gift ($child_name, $gift_name) { my $schema = GiftDB::Schema->get_active_connection(); my $wish = $schema->resultset('Wishlist')->single({ @@ -106,6 +113,7 @@ child's wishlist entry. If we have it, we update the entry to 'delivered'. But how do we test it without actually using a database? We mock the database, that's how! + #!vim perl use builtin qw( true false weaken ); use Test2::V0;