Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

Cucumber, Cuke4Nuke & WatiN

No description
by

David de florinier

on 12 February 2011

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Cucumber, Cuke4Nuke & WatiN

Cucumber & WatiN ...or how can I implement UI Testing without wanting to run away three months later... Gojko Adzic @davedf
http://deflorinier.blogspot.com/ Follow @cuke4ninja Business Rules UI Workflow Let's see an example with Ninjas? Technical Activities Thankyou Document the feature Can be automated Validate the feature Cucumber is a good fit for this I've assumed you know about cucumber already
The main site is cukes.info
Document published on cuke4ninja.com
Follow @cuke4ninja for information about updates Feature: Report on assigned problems
In order to quickly see the bugs I should be working on
As a Ninja Developer
I want to run a run a report that lists all the issues assigned to me

Scenario: Assigned problem
Given there are open issues with the properties
| Title | Severity |
| Chuck Norris beat me | Fatal |
When the issue "Chuck Norris beat me" is assigned to Ninja2
Then Ninja2 sees the following issues in his report
| Title | Severity |
| Chuck Norris beat me | Fatal |
And Ninja1 sees no issues in his report Feature: Report on assigned problems
In order to quickly see the bugs that I should be working on
As a Ninja Developer
I want to run a run a report that lists all the issues assigned to me Scenario: Assigned problem
Given there are open issues with the properties
| Title | Severity |
| Chuck Norris beat me | Fatal |
When the issue "Chuck Norris beat me" is assigned to Ninja2
Then Ninja2 sees the following issues in his report
| Title | Severity |
| Chuck Norris beat me | Fatal |
And Ninja1 sees no issues in his report We are using an open source bug tracking system in this example Called CodeTrack See http://kennwhite.sourceforge.net/codetrack/ for more info Workflow Fluent API Given there are open issues with the properties
| Title | Severity |
| Chuck Norris beat me | Fatal | [Given("^there are open issues with the properties$")]
public void ThereAreOpenIssuesWithThePropertiesWithTable(Table issues)
{
_project = UserWorkflow.LogonAs(Admin)
.CreateNewProject()
.AddIssues(issues.ToIssues())
.CurrentProject;
} When the issue "Chuck Norris beat me" is assigned to Ninja2 [When("^the issue \"(.*)\" is assigned to (.*)$")]
public void TheIssueWithTitleIsAssignedToUser(string issueTitle, string user) {
UserWorkflow.LogonAs(Admin)
.UsingProject(_project)
.AssignIssueToUser(issueTitle, user);
} Then Ninja2 sees the following issues in his report
| Title | Severity |
| Chuck Norris beat me | Fatal | [Then("^(.*) sees the following issues in his report$")]
public void UserSeesTheFollowingIssuesInHisReportWithTable(string user, Table issues) {
IList<Issue> reportedIssues = UserWorkflow.LogonAs(user)
.UsingProject(_project)
.ViewAssignedIssuesReport()
.Issues;

Assert.AreEqual(issues.ToIssues(), reportedIssues);
} And Ninja1 sees no issues in his report [Then("^(.*) sees no issues in his report$")]
public void UserSeesNoIssuesInHisReport(string user) {
Assert.AreEqual(0, UserWorkflow.LogonAs(user)
.UsingProject(_project)
.ViewAssignedIssuesReport()
.NumberOfIssues);
} Implement Workflow as Fluent Objects responsible for an area of the system In this case:
User workflow encapsulates logging in/out and selection of project
Project workflow deals with running report The workflow still doesn't use WatiN though... So, three levels .. Business Workflow Technical Technical Activities Objects should be fine grained
Aim for resuse wherever possible
Writing tests first will tend to produce UI that is suited for testing
Divide UI Elements into symmetric classes Demo? www.cuke4ninja.com Use Domain Language public UserWorkflow logOnAs(String user) {
logOut();
LogonPage logonPage = codeTrack.gotoLogonPage();
logonPage.setName(user);
logonPage.setPassword(user);
codeTrack.submit();
return this;
} public static class TableConverter {
public static IList<Issue> ToIssues(this Table propertiesList) {
var list = new List<Issue>();

foreach (var properties in propertiesList.Hashes()) {
var issue = new Issue(
properties["Title"].Trim(),
properties["Severity"].Trim());
list.Add(issue);
}
return list;
}
} Download the pdf
Read online
O/S on https://github.com/davedf/cuke4ninja Duck and cover,
there's some code ahead.... Let's take a look at how the login works
Logout if already logged in
Navigate to login form
Enter authentication information
Submit the form David de Florinier @gojkoadzic
http://gojko.net/ Feature: Bonus discount

Scenario: basic scenario
Given the user Mike logs on
When the user click on “/home”
And the user enters “Orbital” in the search box
And the page reloads
And the user clicks on “Find tickets” for the first search result
And the page reloads
And the user clicks on “Buy tickets”
And the user enters “Gorillaz” in the search box
And the page reloads
And the user clicks on “Find tickets” for the first search result
And the page reloads
And the user clicks on “Buy tickets”
Then the discount is 10% The principle of symmetric change
One small (refactoring) change to production code should require one small change to the tests
One small change to existing tests should be implementable by a small change in code Business level
Free delivery is offered to customers who order two or more books User Interface Workflow Level
put two books in a shopping cart,
enter address details,
verify that delivery options include free delivery Technical activity level
open the shop homepage,
log in with “testuser” and “testpassword”,
go to the “/book” page,
click on the first image with the “book” CSS class,
wait for page to load,
click on the “Buy now” link http://www.starkravingmadmommy.com/2010/09/texas-is-trying-to-kill-me.html Cuke4Nuke Allows Cucumber to execute step definitions written in .NET

No need to write any Ruby step definitions

https://github.com/richardlawrence/Cuke4Nuke

Cuke4Ninja covers basic usage patterns public class UserWorkflow
{
private readonly CodeTrack _codeTrack;
private readonly ProjectWorkflow _projectWorkflow;

public UserWorkflow(CodeTrack codeTrack)
{
_codeTrack = codeTrack;
_projectWorkflow = new ProjectWorkflow(_codeTrack);
} public ProjectWorkflow CreateNewProject() {
ProjectForm projectForm = _codeTrack.GotoAdminPage().GotoProjectForm();
string projectName = NextProjectName();
projectForm.Name = projectName;
projectForm.Description = "Test Project";
projectForm.Submit();
_codeTrack.GotoHomePage();
return UsingProject(projectName);
} This example uses WatiN to automate the UI http://watin.sourceforge.net/ There is one entry point for the technical layer
WatiN Browser object is injected
IE and Firefox Browsers supported public CodeTrack(string baseUrl,
Browser browser,
UserRepository userRepository)
{
_baseUrl = baseUrl;
_browser = browser;
_userRepository = userRepository;
}
private string Url(string relativePath) {
return string.Format("{0}{1}", _baseUrl, relativePath);
}

public LogonForm GotoLogonPage() {
_browser.GoTo(Url("?page=login"));
return new LogonForm(_browser);
}
public class LogonForm : Form
{
public LogonForm(Browser browser) : base(browser) {}
public string Name {
set {
Browser.TextField(Find.ByName("userLogin[username]"))
.TypeText(value);
}
}

public string Password {
set {
Browser.TextField(Find.ByName("userLogin[password]"))
.TypeText(value);
}
}

}
What we did in the workflow... public class Form : Page {
public Form(Browser browser) : base(browser){}
public virtual void Submit() {
Browser.Button(Find.By("type", "submit")).Click();
}
} Submitting the form Work with application domain wherever possible If you have a domain class representing a UI element or structure, expose that from the technical layer public AssignedIssuesReport ViewAssignedIssuesReport()
{
ReportsPage reportsPage = _codeTrack.GotoReportsPage();
IssueTable issueTable = reportsPage.ShowIssuesAssignedToLoggedInUser();
return new AssignedIssuesReport(issueTable.Issues);
}
public class IssueTable : Page {
public IssueTable(Browser browser) : base(browser) {}
public IList Issues {
get {
IList issues = new List();
var table = Browser.Table(Find.ById("results"));

var rows = table.TableBodies[0].TableRows;
foreach (var row in rows) {
var title = row.TableCells[3].Text;
var severity = row.TableCells[2].Text;
issues.Add(new Issue(title, severity));
}
return issues;
}
}
}
This presentation can be viewed at

http://deflorinier.blogspot.com/2011/02/slides-from-munich-conference-talk.html
Full transcript