testing asp.net - progressive.net

86
@Ben_Hall [email protected] Blog.BenHall.me.uk

Upload: ben-hall

Post on 11-May-2015

4.928 views

Category:

Technology


6 download

DESCRIPTION

Presentation from Progressive.NET 2012 workshop on Testing ASP.NET web applications.

TRANSCRIPT

Page 2: Testing ASP.NET - Progressive.NET

Me?

Page 3: Testing ASP.NET - Progressive.NET

Aim to this talk

• Allow you to make an informed, educated decision for your project.

• Know how to quickly get started if you want to• Know alternative approaches if you don’t

Page 4: Testing ASP.NET - Progressive.NET

Agenda

• UI Browser Automation• Databases and Data Creation• Below the UI Testing• Group therapy

• Pain points, problems, concerns• Best approaches to deal with these

Page 5: Testing ASP.NET - Progressive.NET

What do I mean by ASP.NET automated acceptance testing?

Page 6: Testing ASP.NET - Progressive.NET

DEMO OF AUTOMATED TESTINGGoogle Search

Page 7: Testing ASP.NET - Progressive.NET

var driver = new FirefoxDriver(new FirefoxProfile());driver.Navigate().GoToUrl("http://www.google.co.uk");IWebElement searchbox = driver.FindElement(By.Name("q"));

searchbox.SendKeys("ASP.net");searchbox.SendKeys(Keys.Enter);

var results = driver.FindElement(By.LinkText("Get Started with ASP.NET & ASP.NET MVC : Official Microsoft Site"))

Assert.IsNotNull(results);

Page 8: Testing ASP.NET - Progressive.NET

Testing pipeline

• Outside in, driven from requirements• TDD to drive inside aspects once UI

automated

• Idealistic.. Doesn’t work. Expensive! (Will define this later)

Page 9: Testing ASP.NET - Progressive.NET

Real World...

• Bring flexible to change• Regression testing• Pushing forward, rapidly.• Protecting your own arse

http://4.bp.blogspot.com/-v6mzllgkJlM/Tm-yiM4fPEI/AAAAAAAAE34/7-BEetlvyHo/s1600/matrix1.jpg

Page 10: Testing ASP.NET - Progressive.NET
Page 11: Testing ASP.NET - Progressive.NET

• Focus on solving a pain you have.• Automated UI Testing is one way, which works,

but it’s not the only way.• Hire a manual tester? Short-term gain, long

term pain.

Page 12: Testing ASP.NET - Progressive.NET

Pain you may have in the future

Depends on the system / scenario.UI Tests may not be the best way

Page 13: Testing ASP.NET - Progressive.NET

Spike and Stabilise

Get something out, get feedback, make it right.

Page 14: Testing ASP.NET - Progressive.NET

It’s not all about code quality!

Should not be the driving force

Page 15: Testing ASP.NET - Progressive.NET

• Driving quality of your code via UI tests will kill your motivation for the entire project.

• IT HURTS! Been there, done that!

Page 16: Testing ASP.NET - Progressive.NET

• Focus on what will help you deliver value • Automated tests are expensive.

• How do you define value?• Justify cost by delivering faster? Less bugs?

Company loses less money?

Page 17: Testing ASP.NET - Progressive.NET

Are “bugs” really bugs if they don’t cost the company money nor annoy users?

Page 18: Testing ASP.NET - Progressive.NET

Developers love making things complex

http://xkcd.com/974/

Page 19: Testing ASP.NET - Progressive.NET

WHAT SHOULD YOU TEST?

Page 20: Testing ASP.NET - Progressive.NET

Scenarios

• UI test should focus on scenarios– Behaviour.– Not actions.

Page 21: Testing ASP.NET - Progressive.NET

A single test can save your career

Page 22: Testing ASP.NET - Progressive.NET

Example of a 7digital career saver test

• 1) Can registered users add to basket and checkout?

• 2) Can people register

• Everything else is null and void if those don’t work

Page 23: Testing ASP.NET - Progressive.NET

80/20 Rule

80% of the value comes from 20% of tests

Page 24: Testing ASP.NET - Progressive.NET

Design UI for testability

• Good CSS• Good UX• A bad UX will be extremely difficult to test– Code/Test smell!

Page 25: Testing ASP.NET - Progressive.NET

<div> <div> <p>Some random text</p> <div> <p>Error Message</p> </div> </div></div>

<div> <div> <p>Some random text</p> <div> <p class=“error”>Error Message</p> </div> </div></div>

Much easier to test!

Page 26: Testing ASP.NET - Progressive.NET

Safety net when refactoring legacy code

Page 27: Testing ASP.NET - Progressive.NET

• TDD Rules do apply – naming• TDD doesn’t – single assertion

Page 28: Testing ASP.NET - Progressive.NET

Automated tests against production

• Everything before (TDD, Staging etc) is just a precaution

• If it goes live and it’s dead – it’s pointless.• Focused smoke tests

Page 29: Testing ASP.NET - Progressive.NET

CODE & TOOLS

Page 30: Testing ASP.NET - Progressive.NET

Selenium WebDriver

Page 31: Testing ASP.NET - Progressive.NET

WebDriver is AMAZING!!!

Google, Mozilla, Community

Page 32: Testing ASP.NET - Progressive.NET

Creating a browser instance

new FirefoxDriver(new FirefoxProfile());

new InternetExplorerDriver();

new ChromeDriver(@".")

chromedriver.exe

Page 33: Testing ASP.NET - Progressive.NET

Element Locator Strategies

Basically jQuery

driver.FindElement(By.Name("q"));driver.FindElement(By.ClassName(“error-msg"))driver.FindElement(By.Id("album-list"))

Page 34: Testing ASP.NET - Progressive.NET

Page Interactions

Basically jQuery

.Text

.Click()

.Submit()

.SendKeys() Used for inputing text

Page 35: Testing ASP.NET - Progressive.NET

Executing JS

public static T ExecuteJS<T>(IWebDriver driver, string js) { IJavaScriptExecutor jsExecute = driver as IJavaScriptExecutor; return (T)jsExecute.ExecuteScript(js); }

$(“.NewHeader.header .earn .dropdown-menu”).show();

Page 36: Testing ASP.NET - Progressive.NET

Patiently Waiting

var time = new TimeSpan(0, 0, 30);var timeouts = driver.Manage().Timeouts();timeouts.ImplicitlyWait(time);

Page 37: Testing ASP.NET - Progressive.NET

Patiently Waiting Longer

Use JS code / test hooks in application

window.SWAPP.isReady === true

Page 38: Testing ASP.NET - Progressive.NET

[TestFixtureSetUp] public void CreateDriver() { _driver = new FirefoxDriver(new FirefoxProfile()); _driver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0, 0, 30)); }

[SetUp] public void NavigateToWebpage()

{ _driver.Navigate().GoToUrl(WebApp.URL);}

[TestFixtureTearDown]public void FixtureTearDown() { if (_driver != null) _driver.Close();}

Page 39: Testing ASP.NET - Progressive.NET

But I told everyone to use Ruby

Page 40: Testing ASP.NET - Progressive.NET

When tests fail have good debugging output

Page 41: Testing ASP.NET - Progressive.NET

public static string TakeScreenshot(IWebDriver driver){ string file = Path.GetTempFileName() + ".png";

var s = ((ITakesScreenshot)driver);

s.GetScreenshot().SaveAsFile(file, ImageFormat.Png);

return file;}

Page 42: Testing ASP.NET - Progressive.NET

FUNDAMENTAL PROBLEM

Websites change. Or at least they should.

Page 43: Testing ASP.NET - Progressive.NET

public class ItemListing{ IWebDriver _driver; public ItemListing(IWebDriver driver) { _driver = driver; }

public void AddToCart() { _driver.FindElement(By.Id("addToCart")).Click(); }}

Page 44: Testing ASP.NET - Progressive.NET

TEA PLEASE

Page 45: Testing ASP.NET - Progressive.NET

• MVC Music Store

Page 46: Testing ASP.NET - Progressive.NET

• http://www.github.com• /BenHall/ProgNet2012

• HelloWorldExamples/• Installers/• MVCMusicStore/

Page 47: Testing ASP.NET - Progressive.NET

1. Test that item appears on the homepage2. Automate adding an item to the basket

• Pair – Great opportunity.

Page 48: Testing ASP.NET - Progressive.NET

YOUR TURNhttp://www.github.com/BenHall/ProgNet2012

Page 49: Testing ASP.NET - Progressive.NET

public int HeaderCount(string cartCount) {var regex = new Regex(@"^Cart \((\d+)\)$");

var match = regex.Match(cartCount); var i = match.Groups[1].Captures[0].Value; return Convert.ToInt32(i); }

Page 50: Testing ASP.NET - Progressive.NET

ThanksSo what did I do?

Page 51: Testing ASP.NET - Progressive.NET
Page 52: Testing ASP.NET - Progressive.NET

SLOW!!

http://www.flickr.com/photos/57734740@N00/184375292/

Page 53: Testing ASP.NET - Progressive.NET

Internet Explorer

SetUp : System.InvalidOperationException : Unexpected error launching Internet Explorer. Protected Mode must be set to the same value (enabled or disabled) for all zones. (NoSuchDriver)

Page 54: Testing ASP.NET - Progressive.NET

Complex Xpath / CSS Selectors

table[@id='foo2']/tbody/tr/td/a[contains(text(),'whatever')]

Page 55: Testing ASP.NET - Progressive.NET

Don’t care about the minor details

• CSS downloading correctly... • Other ways to solve that problem without UI

testing

Page 56: Testing ASP.NET - Progressive.NET

Form validation

• Could it be a unit test?• Do you need to run it every time if it hasn’t

changed?• It’s a risk – how calculated is it?

Page 57: Testing ASP.NET - Progressive.NET

DATABASES

Page 58: Testing ASP.NET - Progressive.NET

http://www.flickr.com/photos/gagilas/2659695352/

CACHING

Page 59: Testing ASP.NET - Progressive.NET

http://www.flickr.com/photos/gagilas/2659695352/

LEGACY DATABASE SCHEMA

Page 60: Testing ASP.NET - Progressive.NET

Highly Coupled workflow

• UI Tests become highly coupled to the UI and existing workflow

• UI changes – or at least should. Tests will break, need maintenance etc - BAD

Page 61: Testing ASP.NET - Progressive.NET

Data Builders

• Be able to test website against a clean empty database

• Build only the data your tests need• REALLY hard with a legacy system– Focus on long term and take small steps to get

there

Page 62: Testing ASP.NET - Progressive.NET

Example

var u =new UserCreator(“Name”, 13) .WithOptionalValue(“Of Something”) .WithCart(p1, p2, p3) .Build();

UserDeleter.Delete(u)

Page 63: Testing ASP.NET - Progressive.NET

Simple.Data / Lightweight ORM

db.Users.Insert(Name: "steve", Age: 50)

https://github.com/markrendle/Simple.Data/wiki/Inserting-and-updating-data

Page 64: Testing ASP.NET - Progressive.NET

Shared database

• Be careful• Tests clash• Use random keys when inserting (not 1-10)• Delete only the data you insert

Page 65: Testing ASP.NET - Progressive.NET

TEA PLEASE

Page 66: Testing ASP.NET - Progressive.NET

WHY USE A BROWSER?

Page 67: Testing ASP.NET - Progressive.NET

MVC Test Automation Framework

Hosts ASP.NET in it’s own AppDomainDidn’t work for me.

Page 68: Testing ASP.NET - Progressive.NET

CassiniDev

Page 69: Testing ASP.NET - Progressive.NET

CassiniDevServer server = new CassiniDevServer();server.StartServer(Path.Combine(Environment.Curre

ntDirectory, @"..\..\..\CassiniDevHostingExample"));

string url = server.NormalizeUrl("/");

Page 70: Testing ASP.NET - Progressive.NET

EasyHTTP and CSQuery

Page 71: Testing ASP.NET - Progressive.NET

EasyHTTP – Get / Dynamic

var http = new HttpClient(); http.Request.Accept =

HttpContentTypes.ApplicationJson; var response = http.Get("url"); var customer = response.DynamicBody;Console.WriteLine("Name {0}", customer.Name);

Page 72: Testing ASP.NET - Progressive.NET

EasyHTTP - Post

var customer = new Customer(); customer.Name = "Joe"; customer.Email = "[email protected]"; var http = new HttpClient(); http.Post("url", customer,

HttpContentTypes.ApplicationJson);

Page 73: Testing ASP.NET - Progressive.NET

CSQuery

var sel = dom.Select("a");

var id = dom[0].id;var href = dom[0]["href"];

dom.Each((i,e) => { if (e.id == "remove-this-id") { e.Parent().RemoveChild(e); }

});

Page 74: Testing ASP.NET - Progressive.NET

var url = "http://www.amazon.co.uk/s/ref=nb_sb_noss_2?url=search-alias%3Daps&field-keywords=Testing+ASP.net&x=0&y=0"

var httpClient = new HttpClient();var response = httpClient.Get(url);var dom = CsQuery.CQ.Create(response.RawText);StringAssert.Contains("Ben Hall", dom.Find(".ptBrand").Text());

Page 75: Testing ASP.NET - Progressive.NET

var url = " http://search.twitter.com/search.json?q=prognet&&rpp=5&include_entities=true&result_type=mixed "

var httpClient = new HttpClient(); var response = httpClient.Get(url); Assert.That(response.DynamicBody.results.Length > 0);

Page 76: Testing ASP.NET - Progressive.NET

1. Host MVCMusicStore using CassiniDev2. Test that item appears on the homepage

• Feel free to download completed solution

Page 77: Testing ASP.NET - Progressive.NET

YOUR TURN

Page 78: Testing ASP.NET - Progressive.NET

• Record / Playback• VSTest

• Not every tool helps!

VSTest & Record / Playback

http://www.flickr.com/photos/buro9/298994863/

Page 79: Testing ASP.NET - Progressive.NET

• Chrome Dev Tool + Console - AMAZING

Page 80: Testing ASP.NET - Progressive.NET

http://www.flickr.com/photos/leon_homan/2856628778/

Page 81: Testing ASP.NET - Progressive.NET

Before you write a test think

what would happen if this failed in production for 30 minutes? 4 hours? 3 days?

Would anyone care? Would something else catch it?

Page 82: Testing ASP.NET - Progressive.NET

Focus on true value

Page 83: Testing ASP.NET - Progressive.NET

• Mix different approaches – Hezies 57

http://www.gourmetsteaks.com/wp-content/uploads/steak-sauce-heinz-57.jpg

Page 84: Testing ASP.NET - Progressive.NET
Page 85: Testing ASP.NET - Progressive.NET

“Running UI Tests”

Page 86: Testing ASP.NET - Progressive.NET

http://www.flickr.com/photos/philliecasablanca/2456840986/

@[email protected]