testing asp.net web applications using ruby
DESCRIPTION
Presentation of Testing ASP.net using Ruby I gave at DDD8, January 30th 2010.TRANSCRIPT
![Page 2: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/2.jpg)
1| Why you should care2| Object Level testing3| UI level testing
![Page 3: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/3.jpg)
What do I mean by Testing ASP.net?
![Page 4: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/4.jpg)
Co-Author of Testing ASP.net Web Applicationshttp://www.testingaspnet.com
![Page 5: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/5.jpg)
WHY TEST?
http://www.flickr.com/photos/atomicpuppy/2132073976/
![Page 6: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/6.jpg)
It is 2010. Automated testing is no longer controversial.
![Page 7: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/7.jpg)
[TestMethod]public void EditAction_Retrieves_Dinner_1_From_Repo_And_Countries_And_Sets_DinnerViewModel() { // Arrange var controller = CreateDinnersControllerAs("someuser");
// Act ViewResult result = controller.Edit(1) as ViewResult;
// Assert DinnerFormViewModel model = result.ViewData.Model as DinnerFormViewModel; Assert.AreEqual(13, model.Countries.Count());}
http://nerddinner.codeplex.com/SourceControl/changeset/view/23425#439968
![Page 8: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/8.jpg)
[TestMethod]public void EditAction_Retrieves_Dinner_1_From_Repo_And_Countries_And_Sets_DinnerViewModel() { // Arrange var controller = CreateDinnersControllerAs("someuser");
// Act ViewResult result = controller.Edit(1) as ViewResult;
// Assert DinnerFormViewModel model = result.ViewData.Model as DinnerFormViewModel; Assert.AreEqual(13, model.Countries.Count());}
http://nerddinner.codeplex.com/SourceControl/changeset/view/23425#439968
![Page 9: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/9.jpg)
[Fact] public void RsdReturnsValidRsdDoc() { FakeAreaService areaService = new FakeAreaService();
areaService.StoredAreas.Add("test", new Oxite.Models.Area(false, DateTime.MinValue, null, null, Guid.NewGuid(), DateTime.MinValue, "test"));
RouteCollection routes = new RouteCollection();
routes.Add("Posts", new Route("", new MvcRouteHandler()));
UrlHelper helper = new UrlHelper(new RequestContext(new FakeHttpContext(new Uri("http://oxite.net/"),"~/"), new RouteData()), routes);
Site site = new Site() { Host = new Uri("http://oxite.net") };
AreaController controller = new AreaController(site, areaService, null, null, null, null, null) { Url = helper };
ContentResult result = controller.Rsd("test");
Assert.NotNull(result);
XDocument rsdDoc = XDocument.Parse(result.Content); XNamespace rsdNamespace = "http://archipelago.phrasewise.com/rsd"; XElement rootElement = rsdDoc.Element(rsdNamespace + "rsd");
Assert.NotNull(rootElement); Assert.NotNull(rootElement.Attribute("version")); Assert.Equal("1.0", rootElement.Attribute("version").Value); Assert.Equal("Oxite", rootElement.Descendants(rsdNamespace + "engineName").SingleOrDefault().Value); Assert.Equal("http://oxite.net", rootElement.Descendants(rsdNamespace + "engineLink").SingleOrDefault().Value); Assert.Equal("http://oxite.net/", rootElement.Descendants(rsdNamespace + "homePageLink").SingleOrDefault().Value);
XElement apisElement = rootElement.Descendants(rsdNamespace + "apis").SingleOrDefault(); Assert.NotNull(apisElement); Assert.Equal(1, apisElement.Elements().Count());
XElement apiElement = apisElement.Elements().SingleOrDefault(); Assert.NotNull(apiElement); Assert.Equal(rsdNamespace + "api", apiElement.Name); Assert.Equal("MetaWeblog", apiElement.Attribute("name").Value); Assert.Equal(areaService.StoredAreas["test"].ID.ToString("N"), apiElement.Attribute("blogID").Value); Assert.Equal("true", apiElement.Attribute("preferred").Value); Assert.Equal("http://oxite.net/MetaWeblog.svc", apiElement.Attribute("apiLink").Value); }
http://oxite.codeplex.com/SourceControl/changeset/view/54721#419183
![Page 10: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/10.jpg)
[Fact] public void RsdReturnsValidRsdDoc() { FakeAreaService areaService = new FakeAreaService();
areaService.StoredAreas.Add("test", new Oxite.Models.Area(false, DateTime.MinValue, null, null, Guid.NewGuid(), DateTime.MinValue, "test"));
RouteCollection routes = new RouteCollection();
routes.Add("Posts", new Route("", new MvcRouteHandler()));
UrlHelper helper = new UrlHelper(new RequestContext(new FakeHttpContext(new Uri("http://oxite.net/"),"~/"), new RouteData()), routes);
Site site = new Site() { Host = new Uri("http://oxite.net") };
AreaController controller = new AreaController(site, areaService, null, null, null, null, null) { Url = helper };
ContentResult result = controller.Rsd("test");
Assert.NotNull(result);
XDocument rsdDoc = XDocument.Parse(result.Content); XNamespace rsdNamespace = "http://archipelago.phrasewise.com/rsd"; XElement rootElement = rsdDoc.Element(rsdNamespace + "rsd");
Assert.NotNull(rootElement); Assert.NotNull(rootElement.Attribute("version")); Assert.Equal("1.0", rootElement.Attribute("version").Value); Assert.Equal("Oxite", rootElement.Descendants(rsdNamespace + "engineName").SingleOrDefault().Value); Assert.Equal("http://oxite.net", rootElement.Descendants(rsdNamespace + "engineLink").SingleOrDefault().Value); Assert.Equal("http://oxite.net/", rootElement.Descendants(rsdNamespace + "homePageLink").SingleOrDefault().Value);
XElement apisElement = rootElement.Descendants(rsdNamespace + "apis").SingleOrDefault(); Assert.NotNull(apisElement); Assert.Equal(1, apisElement.Elements().Count());
XElement apiElement = apisElement.Elements().SingleOrDefault(); Assert.NotNull(apiElement); Assert.Equal(rsdNamespace + "api", apiElement.Name); Assert.Equal("MetaWeblog", apiElement.Attribute("name").Value); Assert.Equal(areaService.StoredAreas["test"].ID.ToString("N"), apiElement.Attribute("blogID").Value); Assert.Equal("true", apiElement.Attribute("preferred").Value); Assert.Equal("http://oxite.net/MetaWeblog.svc", apiElement.Attribute("apiLink").Value); }
http://oxite.codeplex.com/SourceControl/changeset/view/54721#419183
![Page 11: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/11.jpg)
[Story] public void Should_find_customers_by_name_when_name_matches() { Story story = new Story("List customers by name"); story.AsA("customer support staff") .IWant("to search for customers in a very flexible manner") .SoThat("I can find a customer record and provide meaningful support");
CustomerRepository repo = null; Customer customer = null; story.WithScenario("Find by name") .Given("a set of valid customers", delegate { repo = CreateDummyRepo(); }) .When("I ask for an existing name", "Joe Schmoe", delegate(string name) { customer = repo.FindByName(name); }) .Then("the correct customer is found and returned", delegate {Assert.That(customer.Name, Is.EqualTo("Joe Schmoe"));}); }
http://grabbagoft.blogspot.com/2007/09/authoring-stories-with-nbehave-03.html
![Page 12: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/12.jpg)
http://www.flickr.com/photos/gagilas/2659695352/
RECORD AND PLAYBACK
![Page 13: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/13.jpg)
You can make C# readable
But it’s hard
![Page 14: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/14.jpg)
RUBY?
http://www.flickr.com/photos/buro9/298994863/
![Page 15: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/15.jpg)
Natural Language
![Page 16: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/16.jpg)
![Page 17: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/17.jpg)
http://www.flickr.com/photos/mag3737/1914076277/
![Page 18: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/18.jpg)
![Page 19: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/19.jpg)
![Page 20: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/20.jpg)
RSpec
http://www.flickr.com/photos/dodgsun/467076780/
![Page 21: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/21.jpg)
Behaviour Driven Development
![Page 22: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/22.jpg)
Intent
![Page 23: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/23.jpg)
[TestMethod]public void EditAction_Retrieves_Dinner_1_From_Repo_And_Countries_And_Sets_DinnerViewModel() { // Arrange var controller = CreateDinnersControllerAs("someuser");
// Act ViewResult result = controller.Edit(1) as ViewResult;
// Assert DinnerFormViewModel model = result.ViewData.Model as DinnerFormViewModel; Assert.AreEqual(13, model.Countries.Count());}
![Page 24: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/24.jpg)
describe
![Page 25: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/25.jpg)
describe “when editing” do
![Page 26: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/26.jpg)
describe “when editing” do itend
![Page 27: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/27.jpg)
describe “when editing” do it “should return countries where dinners can be hosted”end
![Page 28: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/28.jpg)
D:\SourceControl\nerddinner-23425\specs>ispec DinnersController_specs.rb*
Pending:
when editing should return countries where dinners can be hosted (Not Yet Implemented)
./DinnersController_specs.rb:2
Finished in 0.3511328 seconds
1 example, 0 failures, 1 pending
![Page 29: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/29.jpg)
describe NerdDinner::Controllers::DinnersController, “when editing” do
![Page 30: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/30.jpg)
require ‘NerdDinner.dll’describe NerdDinner::Controllers::DinnersController, “when
editing” do
![Page 31: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/31.jpg)
$: << ‘../NerdDinner/bin’require ‘NerdDinner.dll’describe NerdDinner::Controllers::DinnersController, “when
editing” do
![Page 32: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/32.jpg)
$: << ‘../NerdDinner/bin’require ‘NerdDinner.dll’Include NerdDinner::Controllers
describe DinnersController, “when editing” do
![Page 33: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/33.jpg)
it “returns countries where dinners can be hosted” do controller = DinnersController.newend
![Page 34: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/34.jpg)
it “returns countries where dinners can be hosted” do controller = DinnersController.new(dinner_repos(dinners))end
![Page 35: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/35.jpg)
it “returns countries where dinners can be hosted” do controller = DinnersController.new(dinner_repos(dinners)) result = controller.Edit(1).ViewData.Modelend
![Page 36: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/36.jpg)
it “returns countries where dinners can be hosted” do controller = DinnersController.new(dinner_repos(dinners)) result = controller.Edit(1).ViewData.Model result.Countries.Count().should == test_data.lengthend
RSpec has really powerful matchers
![Page 37: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/37.jpg)
D:\SourceControl\nerddinner-23425\specs>ispec DinnersController_specs.rbF
1)'NerdDinner::Controllers::DinnersController when editing should return
countries where dinners can be hosted' FAILEDexpected: 13, got: nil (using ==)./DinnersController_specs.rb:8:Finished in 0.4824219 seconds
1 example, 1 failure
![Page 38: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/38.jpg)
D:\SourceControl\nerddinner-23425\specs>ispec DinnersController_specs.rb.
Finished in 0.4355469 seconds
1 example, 0 failures
![Page 39: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/39.jpg)
require ‘caricature’
def dinner_repos(test_data) IDinnerRepository.isolate(:FindUpcomingDinners) {returns test_data} End
![Page 40: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/40.jpg)
def create_dinners(count=13) dinners = [] count.times do |i| dinners << Dinner.new(:country => “Value#{i}”) endend
![Page 41: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/41.jpg)
describe DinnersController, "when editing" do let(:dinners) {create_dinners} let(:controller) {DinnersController.new(dinner_repos dinners)} it "returns countries where dinners can be hosted" do result = controller.Edit(dinners.first.id).view_model result.Countries.Count().should == dinners.length endend
![Page 42: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/42.jpg)
result.Countries.Count().should == dinners.length result.Countries.should have_same_count(dinners)
module Matchers class CountEqual def initialize(expected) @expected = expected end def matches?(actual) actual.Count() == @expected.Count() end end def have_same_count(expected) CountEqual.new(expected) endend
Duck Typing FTW!
![Page 43: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/43.jpg)
describe DinnersController, “Managing dinner reservations” do let(:dinners) { valid_dinners } let(:controller) {DinnersController.new(dinner_repository dinners)}
describe “when editing“ it_should_behave_like “valid dinners” it "returns countries where dinners can be hosted"
end
describe “when saving“ do describe “the validation for invalid dinners” do let(:dinners) { bad_dinners(1) }
it “should reject a dinner without a name” it “should reject a dinner without a email address” it “should accept a dinner if it has a name and email address” end describe “confirmation” do it “should send an email to the organiser once saved” end describe “valid dinners” do it “redirects to thank you page after completing" end endend
![Page 44: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/44.jpg)
describe "NHibernate" do before do config = Configuration.new @cfg = config.configure(File.join(Dir.pwd, "nhibernate.config")) end
it "can create session factory" do session_factory = @cfg.BuildSessionFactory() session_factory.should_not be_nil end
it "can create session" do session_factory = @cfg.BuildSessionFactory() session = session_factory.open_session session.should_not be_nil endend
![Page 45: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/45.jpg)
Outside-in Development
![Page 46: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/46.jpg)
Cucumber
http://www.flickr.com/photos/vizzzual-dot-com/2738586453/
![Page 47: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/47.jpg)
Documentation, automated tests and development-aid
![Page 48: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/48.jpg)
[Story] public void Should_find_customers_by_name_when_name_matches() {
Story story = new Story("List customers by name"); story.AsA("customer support staff")
.IWant("to search for customers in a very flexible manner")
.SoThat("I can find a customer record and provide meaningful support");
CustomerRepository repo = null; Customer customer = null; story.WithScenario("Find by name")
.Given("a set of valid customers", delegate { repo = CreateDummyRepo(); })
.When("I ask for an existing name", "Joe Schmoe", delegate(string name) { customer = repo.FindByName(name); })
.Then("the correct customer is found and returned", delegate {Assert.That(customer.Name, Is.EqualTo("Joe Schmoe"));});
}
![Page 49: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/49.jpg)
Feature: List customers by name As a customer support staff I want to search for customers in a very flexible manner So that I can find a customer record and provide meaningful support
Scenario: Find by name Given a set of valid customers When I ask for an existing name Then the correct customer is found and returned
![Page 50: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/50.jpg)
Feature: List customers by name As a customer support staff I want to search for customers in a very flexible manner So that I can find a customer record and provide meaningful support
Scenario: Find by name Given a set of valid customers When I ask for an existing name Then the correct customer is found and returned
![Page 51: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/51.jpg)
D:\SourceControl\nerddinner-23425\features>cucumber list.featureFeature: List customers by name As a customer support staff I want to search for customers in a very flexible manner So that I can find a customer record and provide meaningful support
Scenario: Find by name # list.feature:6 Given a set of valid customers # list.feature:7 When I ask for an existing name # list.feature:8 Then the correct customer is found and returned # list.feature:9
1 scenario (1 undefined)3 steps (3 undefined)0m0.020s
You can implement step definitions for undefined steps with these snippets:
Given /^a set of valid customers$/ do pending # express the regexp above with the code you wish you hadend
When /^I ask for an existing name$/ do pending # express the regexp above with the code you wish you hadend
Then /^the correct customer is found and returned$/ do pending # express the regexp above with the code you wish you hadend
![Page 52: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/52.jpg)
Given /^a set of valid customers$/ do @repo = CreateDummyRepo()end
When /^I ask for an existing name$/ do @customer = @repo.FindByName("Joe Schmoe")end
Then /^the correct customer is found and returned$/ do @customer.Name.should == "Joe Schmoe“end
NOT BEST PRACTICE!!
![Page 53: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/53.jpg)
Given /^customer “([^\"]*)” $/ do |name| @repo = CustomerRepository.new(Customer.new(:name => name)end
When /^I search for customer “([^\"]*)”$/ do |name| @customer = @repo.FindByName(name)end
Then /^”([^\"]*)” should be found and returned$/ do |name| @customer.Name.should == nameend
![Page 54: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/54.jpg)
WebRat
http://www.flickr.com/photos/whatwhat/22624256/
![Page 55: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/55.jpg)
visitclick_link
fill_inclick_button
check and uncheckchooseselect
attach_file
![Page 56: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/56.jpg)
EXAMPLESCucumber, WebRat and Automated UI testing
![Page 57: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/57.jpg)
One more thing...
![Page 58: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/58.jpg)
Meerkatalyst
![Page 59: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/59.jpg)
http://blog.benhall.me.uk/2009/12/sneak-peek-at-meerkatalystlonestar.html
![Page 60: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/60.jpg)
http://www.flickr.com/photos/leon_homan/2856628778/
![Page 61: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/61.jpg)
Expressing intent
![Page 62: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/62.jpg)
Ruby -> C#
![Page 64: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/64.jpg)
using Cuke4Nuke.Framework;using NUnit.Framework;using WatiN.Core;namespace Google.StepDefinitions{ public class SearchSteps { Browser _browser; [Before] public void SetUp() { _browser = new WatiN.Core.IE(); } [After] public void TearDown() { if (_browser != null) { _browser.Dispose(); } } [When(@"^(?:I'm on|I go to) the search page$")] public void GoToSearchPage() { _browser.GoTo("http://www.google.com/"); }
[When("^I search for \"(.*)\"$")] public void SearchFor(string query) { _browser.TextField(Find.ByName("q")).TypeText(query); _browser.Button(Find.ByName("btnG")).Click(); } [Then("^I should be on the search page$")] public void IsOnSearchPage() { Assert.That(_browser.Title == "Google"); } [Then("^I should see \"(.*)\" in the results$")] public void ResultsContain(string expectedResult) { Assert.That(_browser.ContainsText(expectedResult)); } }}
![Page 65: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/65.jpg)
Given /^(?:I'm on|I go to) the search page$/ do visit 'http://www.google.com'end When /^I search for "([^\"]*)"$/ do |query| fill_in 'q', :with => query click_button 'Google Search'end Then /^I should be on the search page$/ do dom.search('title').should == "Google"end Then /^I should see \"(.*)\" in the results$/ do |text| response.should contain(text)end
![Page 66: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/66.jpg)
Software
• Recommended:– IronRuby– Ruby– Cucumber– Rspec– WebRat– mechanize– Selenium RC– selenium-client– Caricature– activerecord-sqlserver-
adapter
• Optional:– XSP \ Mono– JetBrain’s RubyMine– JRuby – Capybara– Celerity– Active record – active-record-model-
generator– Faker– Guid
![Page 67: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/67.jpg)
Useful Links• http://www.github.com/BenHall• http://blog.benhall.me.uk• http://stevehodgkiss.com/2009/11/14/using-activerecord-migrator-
standalone-with-sqlite-and-sqlserver-on-windows.html• http://www.testingaspnet.com• http://• http://msdn.microsoft.com/en-us/magazine/dd434651.aspx• http://msdn.microsoft.com/en-us/magazine/dd453038.aspx• http://www.cukes.info
![Page 68: Testing ASP.net Web Applications using Ruby](https://reader035.vdocuments.us/reader035/viewer/2022062513/55593319d8b42a4f3d8b49fe/html5/thumbnails/68.jpg)
Getting SQL Server to work
1. gem install activerecord-sqlserver-adapter1. Download dbi-0.2.2.zip 2. Extract dbd\ADO.rb to ruby\site_ruby\1.8\DBD\
ADO.rb