<div dir="ltr">Hi Chris,<div><br></div><div>Thanks, that's very useful.</div><div><br></div><div>As you suggest, there are no non-technical people on our project who are getting involved with the writing of our cucumber features. I still like the exercise of trying to think about the problem in plain language (in the problem domain) as well as the benefits of end-to-end and regression tests so I still think there is a lot of value in using Cucumber here.</div>
<div><br></div><div style>There are definitely places where the solution has crept into the features we have and you're right to point out that that is causing some of the confusion.</div><div style><br></div><div style>
It sounds like essentially you are saying that the approach is the right one - test the full multi-user journey in a single scenario but that it will make much more sense to do so once we take ourselves away from the solution and we describe that journey using the right language.</div>
<div style><br></div><div style>Cucumber is reasonably new to both of us on the project (one of us is totally new to Rails) so this kind of feedback is very useful.</div><div style><br></div><div style>Thanks</div><div style>
Ian</div><div style><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 29, 2013 at 8:54 PM, Chris Parsons <span dir="ltr"><<a href="mailto:chris.p@rsons.org" target="_blank">chris.p@rsons.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi Ian,<div><br></div><div>I'd start off by taking a step back. Try asking yourself the following questions:</div>
<div><br></div><div>* Who are the people reading this feature who can't read code?</div><div><br></div><div>If there are such people, these features are for them, and need to be written as such using their language - just write down pretty much exactly what they're telling you. If aren't any on this project, then the reason you're writing them is to get your head out of the code and think about the project itself without using technical words at all.</div>
<div><br></div><div>* When reading my feature, am the words to do with the project domain itself, or the solution I'm applying?</div><div><br></div><div>I would suggest that the terms 'logged in', 'subject', 'contents', 'sign out', 'clicks', 'links', 'accept page', and even 'user' are all to do with your solution, rather than the project domain itself, which is why it's hard to get away from the implementation in your feature.</div>
<div><br></div><div>Without knowing your domain, I can't easily help further, but let's assume you're inviting people to participate in test flying fast jets. I might write this scenario like this:</div><div><br>
</div><div>Given I'm a pilot who's been selected for the secret test flight programme</div><div>When I recommend another pilot, Maverick, who I think could help the programme</div><div>Then Maverick should receive an invitation detailing the programme</div>
<div>When he accepts the invitation</div><div>Then he should be informed that he has accepted</div><div><br></div><div>You could implement these steps in any way you chose underneath the hood (email, IM, secure messaging of some sort), which gives you a huge amount of flexibility about how you implement them to cover the intent of the scenario. You've still got an end-to-end test covering the whole journey, the benefit of the regression testing, and good documentation for your non-technical stakeholder.</div>
<div><br></div><div>Matt Wynne wrote a useful post recently which might help further: <a href="http://blog.mattwynne.net/2013/01/17/the-problem-with-solutions/" target="_blank">http://blog.mattwynne.net/2013/01/17/the-problem-with-solutions/</a></div>
<div><br></div><div>HTH</div><div>Chris</div><div><br></div><div>--</div><div>Chris Parsons</div><div><a href="mailto:chrismdp@gmail.com" target="_blank">chrismdp@gmail.com</a></div><div><br></div><div>Training at: <a href="http://bddkickstart.com" target="_blank">http://bddkickstart.com</a></div>
<div><div>Blog: <a href="http://chrismdp.com" target="_blank">http://chrismdp.com</a></div><div>Twitter: <a href="http://twitter.com/chrismdp" target="_blank">http://twitter.com/chrismdp</a></div></div><div><br></div><div>
<div><div class="h5"><div><div>On 29 Jan 2013, at 19:47, Ian Kynnersley <<a href="mailto:iankynnersley@gmail.com" target="_blank">iankynnersley@gmail.com</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr">Hi Graham,<div>
<br></div><div>Thanks for your very helpful response. I think you're right that testing the email contents is a job for a unit test. </div><div><br></div><div>I would still like to have cucumber coverage for the "invited user clicks on the link in the email". However, I guess we could validate that the link in the email is correct in the unit test and then have a cucumber feature that says: </div>
<div><br></div><div>Given I have been invited</div><div>When I visit the "accept invitation" page</div><div>Then I should see ....</div><div><br></div><div><br></div><div>
I also agree that for this app, the controller is probably the right place for these emails to be triggered (although better would be to wrap them in some sort of invitation class).</div><div><br></div><div>And thanks for the Gist. It clarifies it nicely.</div>
<div><br></div><div>Cheers</div><div>Ian</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 29, 2013 at 7:15 PM, Graham Ashton <span dir="ltr"><<a href="mailto:graham@effectif.com" target="_blank">graham@effectif.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On 29 Jan 2013, at 18:35, Ian Kynnersley <<a href="mailto:iankynnersley@gmail.com" target="_blank">iankynnersley@gmail.com</a>> wrote:<br>
<br>
> We are using email_spec (<a href="https://github.com/bmabey/email-spec" target="_blank">https://github.com/bmabey/email-spec</a>) to do the email interaction stuff and it seems to work well but the scenarios end up pretty tortuous.<br>
<br>
</div>I really don't think there's any need to test all that in one test, or with cucumber.<br>
<br>
The first half of your steps are checking that an email gets sent to the right person. The second half just check that the email's subject is correct, and that it has a specific link in it. That sounds a lot like unit testing to me.<br>
<br>
Why are you using cucumber? Are any non technical people on your team eager to read your tests?<br>
<br>
This is how I do it:<br>
<br>
- functional tests on my controller that checks an email gets sent<br>
<br>
- functional tests on my mailer to check they contain the right links<br>
<br>
Here's a gist with the very tests in:<br>
<br>
<a href="https://gist.github.com/4666549" target="_blank">https://gist.github.com/4666549</a><br>
<br>
I've done it this way on a few apps, and have never had any trouble. (The "an" and "the" blocks are from nutrasuite; think of them as "describe".)<br>
<div><br>
> Does this indicate the email should be sent from somewhere else (in the model or maybe a creator class) so that my "Given I have been invited" step will automatically generate the email.<br>
<br>
</div>I wouldn't decide where to send the email from based on whether or not I can persuade my testing framework to see it.<br>
<br>
I'd think about when the email should be sent. For example, if you used an after_create callback on your model you wouldn't be able to create an invitation at the console without sending an email out. If you were doing some admin (e.g. fixing an invitation that didn't get delivered for some reason), that could cause a bunch of unwanted messages to get sent out without you realising.<br>
<br>
Better to make it explicit, and control when the email is sent yourself.<br>
<br>
You could make a method in the model that creates the invite and sends the email (which would be handy if you wanted to invite somebody from the Rails console), or you could just do it in your controller and manually call MyMailer.my_message(my_model).deliver to send an email from the console, should you need to.<br>
<br>
What I'm trying to say is "there's nothing wrong with sending it in the controller".<br>
<div><br>
> Has anyone done this? It is pretty standard behaviour. Does anyone have any recommendations?<br>
<br>
</div>[dons flame proof suit]<br>
<br>
I'd suggest you probably don't need to write a full end to end integration test for it. How necessary it is will depend on your app. What are the failure modes? What will the integration test catch that a handful of unit tests wouldn't?<br>
<br>
If you think "should send an email to invite new users" test in my gist is too lax (in the context of my app it isn't - there's only one email that could get sent), you could just tweak it so that it checks that the last email in ActionMailer::Base.deliveries is the correct message (e.g. by checking the subject).<br>
<br>
--<br>
Graham Ashton<br>
Founder, The Agile Planner<br>
<a href="http://www.theagileplanner.com/" target="_blank">http://www.theagileplanner.com</a> | @agileplanner | @grahamashton<br>
<div><div><br>
<br>
<br>
<br>
_______________________________________________<br>
Chat mailing list<br>
<a href="mailto:Chat@lists.lrug.org" target="_blank">Chat@lists.lrug.org</a><br>
<a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>
<br>Ian Kynnersley<br><a href="http://iankynnersley.co.uk/" target="_blank">http://iankynnersley.co.uk</a> | <a href="tel:%2B44%20%280%29%207973%20420%20829" value="+447973420829" target="_blank">+44 (0) 7973 420 829</a> | <a href="http://twitter.com/kpopper" target="_blank">http://twitter.com/kpopper</a>
</div>
_______________________________________________<br>Chat mailing list<br><a href="mailto:Chat@lists.lrug.org" target="_blank">Chat@lists.lrug.org</a><br><a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
</blockquote></div><br></div></div><div>
<span style="border-collapse:separate;border-spacing:0px">--<br>Chris Parsons<br><a href="mailto:chris.p@rsons.org" target="_blank">chris.p@rsons.org</a><br><a href="http://twitter.com/chrismdp" target="_blank">http://twitter.com/chrismdp</a><br>
<a href="http://pa.rsons.org" target="_blank">http://pa.rsons.org</a><br><br><br><br></span>
</div>
<br></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>
<br>Ian Kynnersley<br><a href="http://iankynnersley.co.uk" target="_blank">http://iankynnersley.co.uk</a> | +44 (0) 7973 420 829 | <a href="http://twitter.com/kpopper" target="_blank">http://twitter.com/kpopper</a>
</div>