Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… ·...
Transcript of Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… ·...
![Page 1: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/1.jpg)
Malte Clasen
Acceptance Tests für Web-UIs
Dr. Malte Clasen
![Page 3: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/3.jpg)
Malte Clasen
Anwendung
![Page 4: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/4.jpg)
Malte Clasen
Anwendung
![Page 5: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/5.jpg)
Malte Clasen
Behavior Driven Development
Write failing
acceptance test
Make unit test
pass
Refactor
Write failing
unit test
![Page 6: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/6.jpg)
Malte Clasen
xUnit
![Page 7: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/7.jpg)
Malte Clasen
ReSharper Test Runner
![Page 8: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/8.jpg)
Malte Clasen
NCrunch
![Page 9: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/9.jpg)
Malte Clasen
NCrunch
![Page 10: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/10.jpg)
Malte Clasen
Gherkin
![Page 11: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/11.jpg)
Malte Clasen
SpecFlow
![Page 12: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/12.jpg)
Malte Clasen
SpecFlow Events
![Page 13: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/13.jpg)
Malte Clasen
FluentAssertions
![Page 14: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/14.jpg)
Malte Clasen
Selenium
![Page 15: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/15.jpg)
Malte Clasen
Chrome
![Page 16: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/16.jpg)
Malte Clasen
PhantomJS
![Page 17: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/17.jpg)
Malte Clasen
Remote Control, Navigation
[Given(@"I am on the homepage")]
public void GivenIAmOnTheHomepage()
{
Web.Navigate().GoToUrl(WebUiContext.RootUrl);
WebUiContext.CatchLog();
}
![Page 18: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/18.jpg)
Malte Clasen
Remote Control, Inject JavaScript
public void CatchLog()
{
_driver.ExecuteScript(@"console.defaultLog=console.log; console.log=function(msg){console.defaultLog(msg); console.logFile+=msg+'\n';};");
}
public string Log
{
get { return (string)_driver.ExecuteScript(
@"return console.logFile;"); }
}
![Page 19: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/19.jpg)
Malte Clasen
Remote Control, Click
[When(@"I follow the ""(.*)"" link")]
public void WhenIFollowTheLink(string linkText)
{
Web.FindElementByLinkText(linkText).Click();
}
![Page 20: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/20.jpg)
Malte Clasen
Remote Control, Type
[When(@"I type ""(.*)""")]
public void WhenIType(string text)
{
CurrentElement.SendKeys(text);
}
![Page 21: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/21.jpg)
Malte Clasen
XPath
[Then(@"there should be the component ""(.*)""")]
public void ThenThereShouldBeTheComponent(string title)
{
EnsureIsInViewOrPreview();
Web.FindElements(By.XPath(ViewXPathPrefix + "//h3"))
.Should().Contain(e => e.Text == title);
}
![Page 22: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/22.jpg)
Malte Clasen
XPath, View Prefix
private string ViewXPathPrefix
{
get
{
EnsureIsInViewOrPreview();
return IsInView
? "//div[@id='Recipe']"
: "//form[@id='RecipeEditor']";
}
}
![Page 23: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/23.jpg)
Malte Clasen
XPath, real world scenario
And the component "Teig" should contain 400 g Mehl
<h2>Zutaten</h2> <h3>Teig</h3> <table class="table table-condensed"> <tbody> <tr class="ingredient"> <td class="amount">400</td> <td class="unit">g</td> <td class="name"> <a href="/Mehl">Mehl</a></td> </tr> </tbody> </table>
![Page 24: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/24.jpg)
Malte Clasen
XPath, real world code
[Then(@"the component ""(.*)"" should contain (.*) (.*) (.*)")]
public void ThenTheComponentShouldContain(string component,
float amount, string unit, string ingredientName)
{
var classFilter = IsInView ? ""
: string.Format("[contains(@class, '{0}')]", EditClass);
Web.FindElements(By.XPath( string.Format(ViewXPathPrefix +
"//h2[.='Zutaten']/following-sibling::h3[.='{0}']/" +
"following-sibling::table{4}//tr[td[1][.='{1}']" +
" and td[2][.='{2}'] and td[3][.='{3}']]", component, amount, unit, ingredientName, classFilter))) .Should().NotBeEmpty();
}
![Page 25: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/25.jpg)
Malte Clasen
XPath, debugging
![Page 26: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/26.jpg)
Malte Clasen
Set Up / Tear Down
benötigte Komponenten
Server
Web Driver
Lebenszyklus
pro Feature
pro Scenario
pro Testlauf (NCrunch: kein [AfterTestRun])
![Page 27: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/27.jpg)
Malte Clasen
Web Driver, Copy to Output
![Page 28: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/28.jpg)
Malte Clasen
Web Driver, Firewall
![Page 29: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/29.jpg)
Malte Clasen
Web Driver, Project Folder
if (NCrunch.Framework.NCrunchEnvironment.
NCrunchIsResident())
return Path.GetDirectoryName(NCrunch.Framework.
NCrunchEnvironment.GetOriginalProjectPath());
return Path.GetDirectoryName(Path.GetDirectoryName(
Path.GetDirectoryName(
AppDomain.CurrentDomain.BaseDirectory))) +
"\\RecipeEditor.Tests";
![Page 30: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/30.jpg)
Malte Clasen
IIS Express
_iisProcess = new Process
{
StartInfo =
{
FileName = programFiles + "\\IIS Express\\iisexpress.exe",
Arguments = string.Format("/path:\"{0}\" /port:{1}",
applicationPath, _iisPort),
WindowStyle = ProcessWindowStyle.Hidden
}
};
![Page 31: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/31.jpg)
Malte Clasen
IIS Express, Praxis
Verhalten sehr nah an IIS
akzeptabel schnell
7 s Set Up / Tear Down pro Feature
1 s pro Test
NCrunch erkennt Code Coverage nicht
![Page 32: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/32.jpg)
Malte Clasen
CassiniDev, Praxis
eingebettet, kein separater Prozess nötig
läuft nur als x86
deutlich langsamere Tests als IIS Express
2 s Set Up / Tear Down pro Feature
6 s pro Test
NCrunch erkennt Code Coverage nicht
![Page 33: Acceptance Tests für Web-UIsmalteclasen.de/blog/wp-content/uploads/2013/06/Acceptance_Tests… · Malte Clasen Remote Control, Click [When(@"I follow the ""(.*)"" link")] public](https://reader036.fdocuments.us/reader036/viewer/2022071020/5fd47a81ef95c70d94269f00/html5/thumbnails/33.jpg)
Malte Clasen
Zusammenfassung
Behavior Driven Development mit Gherkin
Tools speziell: Specflow, Selenium,
PhantomJS, Chrome, IIS Express
Tools allgemein: xUnit, ReSharper,
NCrunch, FluentAssertions
Folien, Code: http://malteclasen.de/blog
Beratung, Training: [email protected]