Writing tests for Dancer::Plugins
Hi, I'm a newbie to Dancer but so far I like a lot of what I see. I wanted to try it out by rewriting some of our crusty old CGI apps to Dancer to give me some experience with it. Needless to say that means the usual coding horrors of old code, no test suite, so many issues that Perl::Critic pretty much just goes "blah". This time around I wanted to keep things modern and include coverage tests, etc. so I'm looking for advice on the best practices within the Dancer community. More specifically I just finished writing a plugin for Dancer but being a plugin I'm not sure how to write the tests. What is considered the best way to approach testing them, whip up a quick dancer app in a test file? Also, since I'm asking for best practice info; 1. Is it considered better to release to Github and then to CPAN per Dancer itself? 2. Are there any guidelines on the naming of Dancer plugins 3. Does any one have any good refs for writing unit tests. Most things I've read so far only say how great their (yet another) Test::* module is, cover the basic stuff over and over. I know how to write the tests, I'm trying to determine what is considered a good level of writing tests. My obsession comes from having discovered that you can Hudson for CI with Perl. Thanks in advance. Colin.
Hey Colin! On Wed, Aug 3, 2011 at 8:06 AM, Colin Keith <colinmkeith@gmail.com> wrote:
Hi,
I'm a newbie to Dancer but so far I like a lot of what I see.
Welcome! Happy to hear you're enjoying yourself. :)
More specifically I just finished writing a plugin for Dancer but being a plugin I'm not sure how to write the tests. What is considered the best way to approach testing them, whip up a quick dancer app in a test file?
Dancer::Test has some shortcomings that made us decide to rewrite it. However, we haven't reached that time yet. We find it useful to use Test::TCP to start a server instance with Dancer, then testing against it. I'm personally still partial to Test::WWW::Mechanize. Feel free to go over our test directory (which is sorted by subjects) to get some impressions of how we find it comfortable to test Dancer. A scaffolding instance of Dancer also includes some tests, to get an understanding of how writing with Dancer::Test looks like.
Also, since I'm asking for best practice info;
1. Is it considered better to release to Github and then to CPAN per Dancer itself?
Usually it's more comfortable for the developer to put a project on Github before releasing it to CPAN, because then you can get feedback from the community and you get a commit history (via git) sooner. There is at least one plugin of which I know that isn't on Github at all, or on any revision control management. Not mine of course. :) This is completely up to you.
2. Are there any guidelines on the naming of Dancer plugins
Yes, though not a lot. * Basically plugins go into the Dancer::Plugin:: namespace. * Try not to pick a namespace that is too generic. We want users to be able to share namespaces when their plugins are related. For example: Dancer::Plugin::Auth::ThisMethod, Dancer::Plugin::Auth::ThatMethod. * When in doubt, simply ask us. :)
3. Does any one have any good refs for writing unit tests. Most things I've read so far only say how great their (yet another) Test::* module is, cover the basic stuff over and over. I know how to write the tests, I'm trying to determine what is considered a good level of writing tests.
The best way is to take a modern project and check out how it writes tests. I use Test::More for most things, Test::Fatal for exception checks, Test::TinyMocker (which we actually wrote as part of Dancer but released separately due to popular demand) for mocking objects. I generally write unit tests. If there's something complicated, I'll write a point-to-point (overall) test and then later break it down to unit tests. Writing in unit tests just helps me understand my code better, notice when and where to refactor it and how the user will use it. My rule of thumb with refactoring is: "if I have to jump through hoops to test this method instead of mocking a few methods (at most), it's too complicated and needs refactoring" - this usually leads me to healthy well-tested code. A few of my modules even reach 100% coverage (not that it's the best metrics). Hope this helps, Sawyer.
On Wednesday 03 August 2011 06:06:07 Colin Keith wrote:
Hi,
I'm a newbie to Dancer but so far I like a lot of what I see.
Welcome to the community :)
More specifically I just finished writing a plugin for Dancer but being a plugin I'm not sure how to write the tests. What is considered the best way to approach testing them, whip up a quick dancer app in a test file?
That's basically the approach used for the tests for Dancer::Plugin::Database https://github.com/bigpresh/Dancer-Plugin-Database/blob/master/t/01-basic.t https://github.com/bigpresh/Dancer-Plugin- Database/blob/master/t/lib/TestApp.pm A test app which exercises the plugin, and a test script that calls the test app and checks the results it gets match what's expected.
1. Is it considered better to release to Github and then to CPAN per Dancer itself?
Generally, yes. Push to GitHub often, and when you're ready to make a stable release, create a tag and release to CPAN (Dist::Zilla can make this very easy, although I've not got round to learning to use it yet, I still do it the old-school way :) )
2. Are there any guidelines on the naming of Dancer plugins
Well, they should start with "Dancer::Plugin::" really; ideally, try not to be too generic if possible to avoid hogging namespaces. Feel free to describe what a plugin does and ask for naming suggestions from the community.
3. Does any one have any good refs for writing unit tests. Most things I've read so far only say how great their (yet another) Test::* module is, cover the basic stuff over and over. I know how to write the tests, I'm trying to determine what is considered a good level of writing tests.
In general, test for expected behaviour in typical cases, and also test for a lack of unexpected behaviour in non-typical cases - e.g. where you don't provide an expected parameter, or provide something potentially odd (for numeric params, say, a zero value, a negative value, etc). It's useful to write tests before fixing bugs for regression testing, too - if a bug is reported, write a test which tickles the bug and fails, then fix the bug - once the test passes, you know you fixed it, and you know if that bug comes back in future, that test will catch it. The Modern Perl book contains a section on testing, although ISTR it's mostly high-level guidance on how to write tests, and doesn't really go into a huge amount of detail on writing *good* tests. Cheers Dave P -- David Precious ("bigpresh") http://www.preshweb.co.uk/ "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)
On Wed, Aug 3, 2011 at 6:00 AM, <dancer-users-request@perldancer.org> wrote:
From: sawyer x <xsawyerx@gmail.com> Subject: Re: [Dancer-users] Writing tests for Dancer::Plugins
Hi, Thanks for the welcome and the information. Sorry for the delayed response. I'm trying to get a project pushed out at work. Also sorry if this reply is out of context, I was subscribed to the list digest when I first posted. I was also wondering if there is a list of any Dancer apps floating around. I saw the links on perldancer.org, but from looking through them it seems that Dancer is being used just for parsing the URLs. That isn't a criticism of course, I'm just super curious and I would like to find some examples of applications built around Dancer so that I can try and learn the style that is used. For example what is the most common method for session storage, data storage, etc. Obviously I'm reading the documentation, but I would love to look through some real-life code too. We currently produce Apache/CGI applications so I think Dancer would be a huge difference since it would likely let us run things much faster and we would be able to slot in new actions so much more easily to make development easier. Of course there's still the convincing the boss part of it that needs to be done :-) but that might be easier with some smaller projects in Dancer.
The best way is to take a modern project and check out how it writes tests. I use Test::More for most things, Test::Fatal for exception checks, Test::TinyMocker (which we actually wrote as part of Dancer but released separately due to popular demand) for mocking objects.
I generally write unit tests. If there's something complicated, I'll write a point-to-point (overall) test and then later break it down to unit tests. Writing in unit tests just helps me understand my code better, notice when and where to refactor it and how the user will use it.
Thank you for the info. I hadn't seen Test::TinyMocker before so I'll look at that. When I write tests (I know, it sounds horrible) I do use Test::More. I mostly wanted to see what suggestions anyone had since the code is available through the application as well as directly in the library.
My rule of thumb with refactoring is: "if I have to jump through hoops to test this method instead of mocking a few methods (at most), it's too complicated and needs refactoring"
Thanks. That is a surprisingly helpful guide to keep in mind.
Hope this helps, Sawyer.
It does. Thank you. Colin.
On Sun, Aug 7, 2011 at 6:43 AM, Colin Keith <colinmkeith@gmail.com> wrote:
Thanks for the welcome and the information. Sorry for the delayed response. I'm trying to get a project pushed out at work. Also sorry if this reply is out of context, I was subscribed to the list digest when I first posted.
Your delayed response? Check out my delayed response! :)
I was also wondering if there is a list of any Dancer apps floating around. I saw the links on perldancer.org, but from looking through them it seems that Dancer is being used just for parsing the URLs.
Since Dancer is a thin layer for routes, it's best used for parsing the URLs for you. A lot of modern applications are centered around Javascript and thus use little code on the backend. While I personally put a lot of logic into the backend, a lot of other applications won't. They won't necessarily feature all their code if it contains a lot of company logics. Also, and this is awesome: Dancer makes you feel more comfortable with short, succinct and subtle code rather than large blobs of it. I've noticed huge applications reduced to clean beautiful (and readable) short code with Dancer. Quite the accomplishment. That isn't a criticism of course, I'm just super curious and I would
like to find some examples of applications built around Dancer so that I can try and learn the style that is used. For example what is the most common method for session storage, data storage, etc. Obviously I'm reading the documentation, but I would love to look through some real-life code too.
Hard to answer this. Different people really do have different needs. You can ask people what they use and get a clearer image, but it's hard for us to point at just one option and say "that's the one". At least when it comes to storage. I personally use encrypted cookies for session information at the moment.
We currently produce Apache/CGI applications so I think Dancer would be a huge difference since it would likely let us run things much faster and we would be able to slot in new actions so much more easily to make development easier. Of course there's still the convincing the boss part of it that needs to be done :-) but that might be easier with some smaller projects in Dancer.
CGI is problematic because: - the code is bigger - it's more complicated - you have to add a lot of stupid logics just for routing users to your real application logic - it's bloated, takes more memory - it's slower - it's harder to add features - it's harder to fix/maintain the current features - it's harder to find people who will work on it - it's harder to find people who will sustain their position for long with it, because working with CGI makes you feel sad By moving to Dancer (or other frameworks) you gain: - shorter code == less to maintain! - less duplication of logic (such as hooks, routes, etc.) - readable code - easy to develop and add features - easy to fix and maintain - faster performance - smaller footprint (more features, less server costs, more users, whatever equation you wanna add here) - easier to find people who will work on it - employees will be happier and keep their job for much longer Once I explained this to my boss, there was no further discussion really. "I'm cutting maintenance headaches and costs, how's that?" -- pretty simple. I hope it works well for you too. :) It's generally a good idea to start with small stuff, seeing them work and then doing bigger stuff. We've currently started writing two small interfaces with Dancer. If they succeed (and why wouldn't they, really?) we'll add a few more. All the best! Sawyer.
participants (3)
-
Colin Keith -
David Precious -
sawyer x