I realise this is a non-trivial task, but is there any way to regression test the styling and rendered layout of a web application? I've found it straight-forward to unittest and regression test functionality, both server-side and client-side. However, a frustrating issue I've run into are CSS changes made to fix one layout issue that break the layout and styling on a different page. The only way I know how to detect these is to manually view every page in an application, and compare it with my own expectations, but obviously this can be burdensome and expensive when an application can have dozens of pages. Has there been any research using image processing or other techniques to detect these kinds of problems automatically?
问题:
回答1:
Actually, one of the hidden gems of Selenium is that you can use it to take screen captures of the browser. Then using a technique as described here (http://www.bryancook.net/2009/10/find-differences-between-images-c.html) you can highlight the differences between previous snapshots.
This example shows how to grab a screenshot of the homepage and then create a difference image. With a little extra tinkering, you can use the same technique to count the pixels that are different.
[Test]
public void CompareHomePageToPrevious()
{
string fileName = Path.Combine(Environment.CurrentDirectory,"homepage.bmp");
var selenium = new DefaultSelenium("localhost",4444, "*chrome", "http://mywebsite");
selenium.Start();
selenium.Open("/");
selenium.CaptureEntirePageScreenshot(fileName, "");
// load current and previous captures
var current = new Bitmap(filename);
var previous = new Bitmap(_previousHomepageImage);
// find all pixels that are the same and make them pink
Bitmap diff = ImageTool.GetDifferenceImage(current,previous,Color.Pink);
diff.MakeTransparent(Color.Pink);
// save the image for viewing
// or count the number of different
}
Selenium is a really interesting choice because it's cross-platform and cross-browser, meaning that you can capture screens of different browsers. You can use this technique to compare snapshots between builds or to compare between browsers.
回答2:
I guess you could generate an 'ideal' shot of each page in your web-app to use as reference.
Then generate a new shot of every page after a css update and compare with the previous ones. A 1:1 comparison should be okay if you make sure you always keep the same resolution, etc.
You could even make it so that you can tell it that if the page differs the other page is actually 'better' than the example and to use the 'other' as the example for the next runs.
That way, when you fix something you can see the difference for one page, and mark it as being better, and then fix a bug on another page while making sure you don't regress the bug you were trying to fix in the first place.
回答3:
There is a way to test layout of a web application using Galen Framework. This tool has its own language and is very easy to learn and understand. It is a Selenium based and you can run test in Selenium Grid, Sauce Labs if you want to test your application in different browsers.
This tool gets the location of specified element on page and check them relatively to each other.
Example: if you want to check that menu pane is below header and stretches to the width of a browser and has 50 pixel height, you can do it like this:
menu
below: header 5px
width: 100% of screen/width
height: 50px
This tool can also be used to test responsive designs.
You can find complete documentation on official website http://galenframework.com
The best part is you can even create JAVA Tests. Galen JavaScript API is also available along with the sample projects in github.
Again, test(s) written once can be used at multiple phases of application lifecycle.
回答4:
If you're developing in ruby, take a look at the rspec-page-regression gem. It's an RSpec plugin that lets you compare requested page snapshots against an expected image. It works with Poltergeist, which is a Capybara driver that uses PhantomJS and supports rendering page snapshots.
Rspec-page-regression provides an RSPec matcher that lets you do things like
context "user page" do
before(:each) do
visit user_path
end
it { page.should match_expected }
context "popup help" do
before(:each) do
click_button "Help"
end
it { page.should match_expected }
end
end
And it provides a mechanism to manage the expectation images.
Disclaimer: I'm the author of the gem.
回答5:
You should check out Web Consistency Testing as an approach to do your regression testing. We use those techniques to power Mogotest, which is a hosted service for doing automated visual regression and cross-browser tests. In the years since this answer was posted, I've shut down the Mogotest service. The mention here is left as a historical artifact to indicate the the techniques were used in a production system and not just academic fodder.