view release on metacpan or search on metacpan
devdata/https_mojolicious.io_blog_2017_12_01_day-1-getting-started view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_01_day-1-getting-started view on Meta::CPAN
<p>In this Advent Calendar series, some posts will be introductory, some will be advanced, some will be on new features.
Who knows what could be next?
But for now let's ensure a level playing field by working out how to get started.</p>
</section>
<section id="section-2">
<h2>What is Mojolicious?</h2>
<p>Well, <a href="http://mojolicious.org">Mojolicious</a> is really two things.
First it is a powerful web-focused toolkit called Mojo.
Second it is a powerful web framework called Mojolicious.
The Mojolicious framework is built using the Mojo toolkit.</p>
<p>That that doesn't mean you can't use Mojo tools elsewhere.
If you see some tools you like but want to use with some other framework, go ahead, I won't tell!
Use it in any Perl code you want!</p>
<p>Shoot I wasn't going to mention Perl!
Yes, Mojolicious is written in Perl.
Don't let that scare you.
It has tons of ways to keep you and your code safe!
From a built-in object system to a consistent API with chainable methods, Mojolicious is designed to keep your code clean and readable.
Hopefully you'll even have some fun using it!</p>
<h2>Installation</h2>
devdata/https_mojolicious.io_blog_2017_12_02_day-2-the-stash view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_02_day-2-the-stash view on Meta::CPAN
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="leather bag" src="/blog/2017/12/02/day-2-the-stash/bag-1854148_1920.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>In Mojolicious, when processing a request and preparing a response one of the most important concepts is "the stash".
Since it is a non-blocking framework, your code can't use global variables to store any state during processing.
If you did and some other code were to run, it could very easily get cross-talk between requests.</p>
<p>The stash is the place you can store information while you process it.
It is just a simple hash reference that is attached to the controller object that is processing the request.
It lives and dies with that one transaction.</p>
<p>While you can and should use it as a scratchpad, it really is much more.
The stash controls almost every aspect of the response that you generate.
Let's look a little closer to see how it works</p>
devdata/https_mojolicious.io_blog_2017_12_03_day-3-using-named-routes view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_04_day-4-dont-fear-the-full-app view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_05_day-5-your-apps-built-in-commands view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_06_day-6-adding-your-own-commands view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_07_day-7-using-template-variants-for-a-beta-landing-page view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_08_day-8-mocking-a-rest-api view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_09_day-9-the-best-way-to-test view on Meta::CPAN
<link href="/theme/css/default.css" rel="stylesheet">
<link href="/theme/css/layout.css" rel="stylesheet">
<link href="/theme/css/media-queries.css" rel="stylesheet">
<link href="/theme/css/statocles.css" rel="stylesheet">
<!-- twitter and opengraph -->
<meta content="summary" name="twitter:card">
<meta content="@joelaberger" name="twitter:creator">
<meta content="https://mojolicious.io/blog/2017/12/09/day-9-the-best-way-to-test/" property="og:url">
<meta content="Day 9: The Best Way to Test" property="og:title">
<meta content="An introduction to Test::Mojo, the testing framework for Mojolicious." property="og:description">
<meta content="https://mojolicious.io/blog/2017/12/09/day-9-the-best-way-to-test/1280px-CSIRO_ScienceImage_2798_Testing_in_the_Laboratory.jpg" property="og:image">
<meta content="summary_large_image" name="twitter:card">
<script src="/theme/js/modernizr.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/sunburst.min.css" rel="stylesheet">
<title>Day 9: The Best Way to Test - mojolicious.io</title>
<meta content="Joel Berger" name="author">
<meta content="Statocles 0.093" name="generator">
devdata/https_mojolicious.io_blog_2017_12_09_day-9-the-best-way-to-test view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_09_day-9-the-best-way-to-test view on Meta::CPAN
<!-- theme suggests 1300x500 -->
<img alt="Woman using chemistry lab equipment" src="/blog/2017/12/09/day-9-the-best-way-to-test/1280px-CSIRO_ScienceImage_2798_Testing_in_the_Laboratory.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p>Ok so it is a bit of a click-bait headline.
But that doesn't mean I don't believe it.</p>
<p><a href="http://mojolicious.org/perldoc/Test/Mojo">Test::Mojo</a> is a test framework for websites and related technologies.
While its true that there are many such tools, this one gets its power comes from combining so many of the tools that Mojolicious provides.
A full non-blocking web server, including websockets, an <a href="http://mojolicious.org/perldoc/Mojo/IOLoop">event loop</a>, an <a href="http://mojolicious.org/perldoc/Mojo/DOM">XML/HTML DOM parser</a>, <a href="http://mojolicious.org/perldoc/Mojo/J...
Further, with the recent additions in support of <a href="http://mojolicious.org/perldoc/Mojo/Base#with_roles">roles</a> (which will be discussed in a future post), Test::Mojo is becoming an extensible testing platform.</p>
<p>In this article, I'll give a quick overview of how to use Test::Mojo and some of its methods.
Rest assured you'll see more of it as the series continues.</p>
</section>
<section id="section-2">
<h2>Getting Started</h2>
devdata/https_mojolicious.io_blog_2017_12_09_day-9-the-best-way-to-test view on Meta::CPAN
my $t = Test::Mojo->new($app);
</code></pre>
<h2>How It Works</h2>
<p>Test::Mojo contains an instance of <a href="http://mojolicious.org/perldoc/Mojo/UserAgent">Mojo::UserAgent</a> which it uses to make requests.
What many people don't know is that Mojo::UserAgent can act as a <a href="http://mojolicious.org/perldoc/Mojo/UserAgent#server">server</a> for a Mojo application!
When the useragent gets a request for a relative url, (i.e. without a protocol or host), it uses this embedded server to fulfil the request.
This isn't just useful for Test::Mojo, but that is its primary purpose.</p>
<p>Many testing frameworks in Perl start some kind of fake server, mimicing the request/response cycle.
That works in blocking scenarios, but once you add non-blocking to the mix there is no substitute for a real server.
The useragent's server actually starts up on two different (local-only) ports, one for blocking requests and one for non-blocking.
Most people don't need to worry about that but for doing very complex things, knowing that might help.</p>
<p>When you make a request with Test::Mojo, its useragent will make the request, whether locally or externally and return to it the <a href="http://mojolicious.org/perldoc/Mojo/Transaction">transaction</a> object.
Test::Mojo then keeps that object in its <a href="http://mojolicious.org/perldoc/Test/Mojo#tx">tx</a> attribute for subsequent tests until the next request is made.
If none of the test methods that it provides will allow you to test what you need, you are welcome to fish the data out of that object.</p>
<p>When you use Test::More, when a test fails the test function returns a false value, allowing you to take some action on failure.</p>
devdata/https_mojolicious.io_blog_2017_12_10_day-10-give-the-customer-what-they-want view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_11_day-11-useragent-content-generators view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_12_day-12-more-than-a-base-class view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_12_day-12-more-than-a-base-class view on Meta::CPAN
<p>First it imports several handy pragma that make your code safer and some features that are useful.
Second, it can be a base class to the current package, or establish a parent class, or even define a role.
Let's see how it does it.</p>
</section>
<section id="section-2">
<h2>Importing Pragma and Functionality</h2>
<p>Most of the authors in the modern Perl commmunity recommend that all Perl code use the <a href="https://metacpan.org/pod/strict">strict</a> and <a href="https://metacpan.org/pod/warnings">warnings</a> pragmas.
Like many of the major Perl object frameworks, <a href="https://metacpan.org/pod/Moose">Moose</a> and <a href="https://metacpan.org/pod/Moo">Moo</a> included, Mojo::Base feels these are important enough that it imports them for you.
Unlike those others, it goes further.</p>
<p>Since the modern web is trending towards UTF-8 encoding, the <a href="https://metacpan.org/pod/utf8">utf8</a> pragma is loaded; this enables you to use UTF-8 encoded characters right in your script.
Mojolicious does much of your web-facing encoding for you so this <strong>almost</strong> means you don't have to think about character encoding at all!</p>
<p>And because Mojolicious itself requires Perl 5.10, it also enables all of the <a href="https://metacpan.org/pod/feature">features</a> that came with that version.
This includes <a href="https://www.effectiveperlprogramming.com/2009/12/perl-5-10-new-features/">handy functionality</a> like the <code>state</code> and <code>say</code> keywords as well as the defined-or operator <code>//</code>.
Finally it imports IO::Handle so that all of your handles behave as objects (if you don't know what that means or why, don't worry about it).</p>
<p>If this is the only thing you want from Mojo::Base, perhaps in a script or a test file, all you do is pass the <code>-strict</code> flag</p>
devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_13_day-13-more-about-roles view on Meta::CPAN
</code></pre>
<h2>Roles on CPAN</h2>
<p>The first part of the ecosystem to embrace roles was testing.
Given the interface of <a href="http://mojolicious.org/perldoc/Test/Mojo">Test::Mojo</a>, adding additional test methods isn't as easy as is generally true of other testers in the <a href="https://metacpan.org/pod/Test::More">Test::More</a> lands...
Roles fill that gap nicely, and therefore such roles predated Mojo::Base's own role handling and even inspired adding it to the core.</p>
<p>As I've mentioned <a href="/blog/2017/12/09/day-9-the-best-way-to-test">earlier in this series</a>, <a href="https://metacpan.org/pod/Test::Mojo::Role::Debug">Test::Mojo::Role::Debug</a> adds methods to run a callback on failed tests.
<a href="https://metacpan.org/pod/Test::Mojo::Role::TestDeep">Test::Mojo::Role::TestDeep</a> lets you test responses with the comparison functions from <a href="https://metacpan.org/pod/Test::Deep">Test::Deep</a>.
<a href="https://metacpan.org/pod/Test::Mojo::Role::PSGI">Test::Mojo::Role::PSGI</a> lets you use Test::Mojo with non-Mojolicious web frameworks!
You can even use them all together.</p>
<pre><code>use Mojo::Base -strict;
use Test::More;
use Test::Mojo;
use Test::Deep; # for its keywords
my $t = Test::Mojo
->with_roles('+PSGI', '+TestDeep', '+Debug')
->new('/path/to/app.psgi');
devdata/https_mojolicious.io_blog_2017_12_14_day-14-you-promised-to-call view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_14_day-14-you-promised-to-call view on Meta::CPAN
<section id="section-1">
<p>A new feature of <a href="http://mojolicious.org/">Mojolicious</a>, as of <a href="https://metacpan.org/release/SRI/Mojolicious-7.49">7.49</a>, is the implementation of the <a href="https://promisesaplus.com/implementations#in-ot...
</section>
<section id="section-2">
<h2>Background</h2>
<p>"Normal" Perl code runs synchronously: it does each step it is told to, one at a time, and only that. This is also known as "blocking", since the program cannot do anything else.</p>
<p>The essence of a non-blocking code framework is that if you are waiting for something, you can register with the framework what to do when that thing happens. It can then do other processing tasks in the meantime. This means you don't have lot...
<p>Originally this was done just using callbacks, but this lead to what is known as "callback hell": each callback contains the next callback, at an increasing level of indentation. Even harder to keep track of is if the functions are kept ...
<p>Promises are used to easily add processing steps to a transaction: one can keep adding code for what to do "then" - after a previous stage has finished. Best of all, each "callback" is small and separate, with each one placed i...
<p>First let's get web pages, one after the other, synchronously. Obviously, that means the code will block anything else while it's running.</p>
<pre><code># refers to a previously-set-up @urls
sub fetchpages {
while (my $url = shift @urls) {
devdata/https_mojolicious.io_blog_2017_12_15_day-15-start-a-new-yancy-app view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_15_day-15-start-a-new-yancy-app view on Meta::CPAN
<div class="post-thumb">
<!-- theme suggests 1300x500 -->
<img alt="Workers on a scaffold" src="/blog/2017/12/15/day-15-start-a-new-yancy-app/scaffold.jpg">
</div>
<div class="post-content">
<section id="section-1">
<p><a href="http://metacpan.org/pod/Yancy">Yancy</a> is a new content management
plugin for the <a href="http://mojolicious.org">Mojolicious web framework</a>.
Yancy allows you to easily administrate your siteâÂÂs content just by
describing it using <a href="http://json-schema.org">JSON Schema</a>. Yancy
supports <a href="http://metacpan.org/pod/Yancy::Backend">multiple backends</a>, so
your site's content can be in
<a href="http://metacpan.org/pod/Yancy::Backend::Pg">Postgres</a>,
<a href="http://metacpan.org/pod/Yancy::Backend::Mysql">MySQL</a>, and
<a href="http://metacpan.org/pod/Yancy::Backend::Dbic">DBIx::Class</a>.</p>
</section>
<section id="section-2">
devdata/https_mojolicious.io_blog_2017_12_16_day-16-the-secret-life-of-sessions view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_17_day-17-the-wishlist-app view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_18_day-18-the-wishlist-model view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_19_day-19-make-your-app-installable view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_20_day-20-practical-testing view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_21_day-21-virtually-a-lumberjack view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_21_day-21-virtually-a-lumberjack view on Meta::CPAN
@@ pgm_header
P2
00000000 00000000
255
</code></pre>
<p>This script will create 0_START.pgm, add a PGM header to it (which will need
fixing later) and writes the bytes it receives from STDIN into that file in
the correct format.</p>
<p>We have used various bits from the Mojolicious framework to achieve this.
<a href="http://mojolicious.org/perldoc/Mojo/Loader">Mojo::Loader</a> lets us put our PGM
header separate from the rest of the code, just like an inline template for a
Lite app.
Since it is usually used to receive file uploads,
<a href="http://mojolicious.org/perldoc/Mojo/Asset/File">Mojo::Asset::File</a> gives us
even simpler file creation and append mechanics than
<a href="http://mojolicious.org/perldoc/Mojo/File">Mojo::File</a>, for outputting the
re-formatted data input.
We do have to tell Mojolicious not to <em>cleanup</em> the file once it is done with
it, though this is small price to pay!
devdata/https_mojolicious.io_blog_2017_12_22_day-22-how-to-build-a-public-rest-api view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_23_day-23-one-liners-for-fun-and-profit view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">
devdata/https_mojolicious.io_blog_2017_12_24_day-24-release-and-wrap-up view on Meta::CPAN
</header>
<div id="page-title">
<div class="row">
<div class="ten columns centered text-center">
<h1>Mojo Wonk Blog<span>.</span></h1>
<p>A semi-offical blog dedicated to the Mojolicious web framework</p>
</div>
</div>
</div>
<div class="content-outer">