public class ScreenShotDifferTest { private final long DEVIATION = 20L; private WebDriver driver = new FirefoxDriver(); public ScreenShooter screenShooter = new ScreenShooter(); @Test public void originPageShouldBeSameAsModifiedPage() throws Exception { BufferedImage originScreenShot = screenShooter.takeScreenShot("http://www.yandex.ru", driver); BufferedImage modifiedScreenShot = screenShooter.takeScreenShot("http://beta.yandex.ru", driver); long diffPixels = screenShooter.diff(originScreenShot, modifiedScreenShot); assertThat(diffPixels, lessThan(DEVIATION); } @After public void closeDriver() { driver.quit(); } }
@RunWith(Parameterized.class) public class ScreenShotDifferTest { ... private String originPageUrl; private String modifiedPageUrl; public ScreenShotDifferTest (String originPageUrl, String modifiedPageUrl) { this.modifiedPageUrl = modifiedPageUrl; this.originPageUrl = originPageUrl; } @Parameterized.Parameters(name = "{0}") public static Collection<Object[]> readUrlPairs () { return Arrays.asList( new Object[]{"Yandex Main Page", "http://www.yandex.ru/", "http://beta.yandex.ru/"}, new Object[]{"Yandex.Market Main Page", "http://market.yandex.ru/", "http://beta.market.yandex.ru/"} ); } ... }
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:report.examples.qatools.yandex.ru" targetNamespace="urn:report.examples.qatools.yandex.ru" version="2.1"> <xsd:element name="testCaseResult" type="ns:TestCaseResult"/> <!-- --> <xsd:complexType name="TestCaseResult"> <xsd:sequence> <xsd:element name="description" type="xsd:string"/> <!-- --> <xsd:element name="origin" type="ns:ScreenShotData" nillable="false"/> <!-- ( )--> <xsd:element name="modified" type="ns:ScreenShotData" nillable="false"/> <!-- ( )--> <xsd:element name="diff" type="ns:DiffData" nillable="false"/> <!-- --> <xsd:element name="message" type="xsd:string"/> <!-- , --> </xsd:sequence> <xsd:attribute name="uid" type="xsd:string"/> <!--ID- --> <xsd:attribute name="title" type="xsd:string"/> <!-- , --> <xsd:attribute name="status" type="ns:Status"/> <!-- --> </xsd:complexType> <xsd:complexType name="ScreenShotData"> <xsd:sequence> <xsd:element name="pageUrl" type="xsd:string"/> <!-- , --> <xsd:element name="fileName" type="xsd:string"/> <!-- --> </xsd:sequence> </xsd:complexType> <xsd:complexType name="DiffData"> <xsd:sequence> <xsd:element name="pixels" type="xsd:long" default="0"/> <!-- --> <xsd:element name="fileName" type="xsd:string"/><!-- --> </xsd:sequence> </xsd:complexType> <xsd:simpleType name="Status"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="OK"/> <xsd:enumeration value="FAIL"/> <xsd:enumeration value="ERROR"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>
/** * <p>Java class for TestCaseResult complex type. * * <p>The following schema fragment specifies the expected content contained within this class. * * <pre> * <complexType name="TestCaseResult"> * <complexContent> * <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> * <sequence> * <element name="message" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="description" type="{http://www.w3.org/2001/XMLSchema}string"/> * <element name="origin" type="{urn:report.examples.qatools.yandex.ru}ScreenShotData"/> * <element name="modified" type="{urn:report.examples.qatools.yandex.ru}ScreenShotData"/> * <element name="diff" type="{urn:report.examples.qatools.yandex.ru}DiffData"/> * </sequence> * <attribute name="uid" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="title" type="{http://www.w3.org/2001/XMLSchema}string" /> * <attribute name="status" type="{urn:report.examples.qatools.yandex.ru}Status" /> * </restriction> * </complexContent> * </complexType> * </pre> * * */ @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "TestCaseResult", propOrder = { "message", "description", "origin", "modified", "diff" }) public class TestCaseResult { @XmlElement(required = true) protected String message; @XmlElement(required = true) protected String description; @XmlElement(required = true) protected ScreenShotData origin; @XmlElement(required = true) protected ScreenShotData modified; @XmlElement(required = true) protected DiffData diff; @XmlAttribute(name = "uid") protected String uid; @XmlAttribute(name = "title") protected String title; @XmlAttribute(name = "status") protected Status status; /** * Gets the value of the message property. * * @return * possible object is * {@link String } * */ public String getMessage() { return message; } /** * Sets the value of the message property. * * @param value * allowed object is * {@link String } * */ public void setMessage(String value) { this.message = value; } /** * Gets the value of the description property. * * @return * possible object is * {@link String } * */ public String getDescription() { return description; } /** * Sets the value of the description property. * * @param value * allowed object is * {@link String } * */ public void setDescription(String value) { this.description = value; } /** * Gets the value of the origin property. * * @return * possible object is * {@link ScreenShotData } * */ public ScreenShotData getOrigin() { return origin; } /** * Sets the value of the origin property. * * @param value * allowed object is * {@link ScreenShotData } * */ public void setOrigin(ScreenShotData value) { this.origin = value; } /** * Gets the value of the modified property. * * @return * possible object is * {@link ScreenShotData } * */ public ScreenShotData getModified() { return modified; } /** * Sets the value of the modified property. * * @param value * allowed object is * {@link ScreenShotData } * */ public void setModified(ScreenShotData value) { this.modified = value; } /** * Gets the value of the diff property. * * @return * possible object is * {@link DiffData } * */ public DiffData getDiff() { return diff; } /** * Sets the value of the diff property. * * @param value * allowed object is * {@link DiffData } * */ public void setDiff(DiffData value) { this.diff = value; } /** * Gets the value of the uid property. * * @return * possible object is * {@link String } * */ public String getUid() { return uid; } /** * Sets the value of the uid property. * * @param value * allowed object is * {@link String } * */ public void setUid(String value) { this.uid = value; } /** * Gets the value of the title property. * * @return * possible object is * {@link String } * */ public String getTitle() { return title; } /** * Sets the value of the title property. * * @param value * allowed object is * {@link String } * */ public void setTitle(String value) { this.title = value; } /** * Gets the value of the status property. * * @return * possible object is * {@link Status } * */ public Status getStatus() { return status; } /** * Sets the value of the status property. * * @param value * allowed object is * {@link Status } * */ public void setStatus(Status value) { this.status = value; } }
TestCaseResult testCaseResult = ... JAXB.marshal(testCaseResult, file);
TestCaseResult testCaseResult = JAXB.unmarshal(file, TestCaseResult.class)
public abstract class TestWatcher implements org.junit.rules.TestRule { // protected void starting(org.junit.runner.Description description) {...} // protected void succeeded(org.junit.runner.Description description) {...} // , // // !!()!! assumeThat() protected void skipped(org.junit.internal.AssumptionViolatedException e, org.junit.runner.Description description) {...} // protected void failed(java.lang.Throwable e, org.junit.runner.Description description) {...} // protected void finished(org.junit.runner.Description description) {...} }
protected void starting(org.junit.runner.Description description)
- add to it the initialization of the TestCaseResult model and the creation of all the necessary files. protected void succeeded(org.junit.runner.Description description)
- in it we will put down the status OK of our test execution. protected void skipped(org.junit.internal.AssumptionViolatedException e, org.junit.runner.Description description)
- we are not interested in this method. It can be left unchanged. protected void failed(java.lang.Throwable e, org.junit.runner.Description description)
- here we will have conditional logic. If a e instanceOf AssertionViolatedException
, then an error (FAIL) occurred in the test, in any other case the test was broken (ERROR). protected void finished(org.junit.runner.Description description)
- here we serialize the TestCaseResult object into xml. public BufferedImage takeOriginScreenShot(String url)
- remove the screenshot of the original page by url, save the screenshot on the file system, link to the data and return BufferedImage. public BufferedImage takeModifiedScreenShot(String url)
- the same operations, only for the page of the candidate. public DiffData diff(BufferedImage original, BufferedImage modified)
- we get diff of two screenshots, save to the file system, link to the data and return the object with information about the differences.target/site/custom
directory, as it is the default for reports. @RunWith(Parameterized.class) public class ScreenShotDifferTest { private String originPageUrl; private String modifiedPageUrl; ... @Rule public ScreenShotDifferRule screenShotDiffer = new ScreenShotDifferRule(driver); public ScreenShotDifferTest(String title, String originPageUrl, String modifiedPageUrl) { this.modifiedPageUrl = modifiedPageUrl; this.originPageUrl = originPageUrl; } ... @Test public void originShouldBeSameAsModified() throws Exception { BufferedImage originScreenShot = screenShotDiffer.takeOriginScreenShot(originPageUrl); BufferedImage modifiedScreenShot = screenShotDiffer.takeModifiedScreenShot(modifiedPageUrl); long diffPixels = screenShotDiffer.diff(originScreenShot, modifiedScreenShot); assertThat(diffPixels, lessThan((long) 20)); } ... }
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <testCaseResult status="OK" title="originShouldBeSameAsModified[0](ru.yandex.qatools.examples.report.ScreenShotDifferTest)" uid="ru.yandex.qatools.examples.report.ScreenShotDifferTest.originShouldBeSameAsModified[0]"> <origin> <pageUrl>http://www.yandex.ru/</pageUrl> <fileName>{uid}-origin.png</fileName> </origin> <modified> <pageUrl>http://www.yandex.ru/</pageUrl> <fileName>{uid}-modified.png</fileName> </modified> <diff> <pixels>0</pixels> <fileName>{uid}-diff.png</fileName> </diff> </testCaseResult>
= "originShouldBeSameAsModified [ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <testCaseResult status="OK" title="originShouldBeSameAsModified[0](ru.yandex.qatools.examples.report.ScreenShotDifferTest)" uid="ru.yandex.qatools.examples.report.ScreenShotDifferTest.originShouldBeSameAsModified[0]"> <origin> <pageUrl>http://www.yandex.ru/</pageUrl> <fileName>{uid}-origin.png</fileName> </origin> <modified> <pageUrl>http://www.yandex.ru/</pageUrl> <fileName>{uid}-modified.png</fileName> </modified> <diff> <pixels>0</pixels> <fileName>{uid}-diff.png</fileName> </diff> </testCaseResult>
ru.yandex.qatools.examples.report.ScreenShotDifferTest.originShouldBeSameAsModified [ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <testCaseResult status="OK" title="originShouldBeSameAsModified[0](ru.yandex.qatools.examples.report.ScreenShotDifferTest)" uid="ru.yandex.qatools.examples.report.ScreenShotDifferTest.originShouldBeSameAsModified[0]"> <origin> <pageUrl>http://www.yandex.ru/</pageUrl> <fileName>{uid}-origin.png</fileName> </origin> <modified> <pageUrl>http://www.yandex.ru/</pageUrl> <fileName>{uid}-modified.png</fileName> </modified> <diff> <pixels>0</pixels> <fileName>{uid}-diff.png</fileName> </diff> </testCaseResult>
public void exec ()
method. In our case, it should: File[] testCasesFiles = listOfFiles(reportDirectory, ".*-testcase\\.xml");
List<TestCaseResult> testCases = convert(testCasesFile, new Converter<File, TestCaseResult>(){ public TestCaseResult convert (File file) { return JAXB.unmarshall(file, TestCaseResult.xml); } });
String source = processTemplate(TEMPLATE_NAME, testCases);
Sink sink = new Sink(); sink.setHtml(source); sink.close();((
mvn clean install
command. For simplicity, you can download the project github.com/yandex-qatools/tests-report-example and execute a command for it. As a result of the command execution in the tests-report-example module in the target / site / directory, you will see a project report .mvn clean install
command in the project root. After its execution, we will get artifacts ready for use. We connect our newly created plugin to the autotest project together with the standard surefire plugin. <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> <version>3.2</version> <configuration> <reportPlugins> <plugin> <groupId>ru.yandex.qatools.examples</groupId> <artifactId>custom-report-plugin</artifactId> <version>${project.version}</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-report-plugin</artifactId> <version>2.14.1</version> </plugin> </reportPlugins> </configuration> </plugin>
mvn clean site
.Source: https://habr.com/ru/post/200364/
All Articles