zoukankan      html  css  js  c++  java
  • 基于WebDriver&TestNG 实现自己的Annotation @TakeScreenshotOnFailure

    相信用过Selenium WebDriver 的朋友都应该知道如何使用WebDriver API实现Take Screenshot的功能。

    在这篇文章里,我主要来介绍对failed tests实现 take screenshot的功能, 并且我们也高大上一回,做成注解的形式。

    效果如下:

    目录
        前提
        Maven 配置
        Example
        简单类图
         TakeScreenshotOnFailure CustomTestListener WebDriverHost TestBase DemoListenerTest TestNG.xml Run as TestNG

      

    前提

    • JDK 1.7
    • Maven 3

    Maven 配置

            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>6.9.5</version>
            </dependency>
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
                <version>2.46.0</version>
            </dependency>

    Example

    简单类图

    首先创建一个类 如下 TakeScreenshotOnFailure.java

    package test.demo;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Annotation informs CustomTestListener to take screenshot if test method fails. File name is method name + png suffix.
     * Test class must implement WebDriverHost in order for the screenshot to work.
     * 
     * @author wadexu
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(value =
      {ElementType.METHOD})
    public @interface TakeScreenshotOnFailure {
    }

     ##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html 

    然后创建一个自己的CustomTestListener 继承TestNG 的 TestListenerAdapter 重写onTestFailure()方法, 加入take screenshot的功能

    代码如下

    package test.demo;
    
    import java.io.File;
    import java.lang.reflect.Method;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.log4j.Logger;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    
    import org.testng.ITestResult;
    import org.testng.TestListenerAdapter;
    
    /**
    * 
    * @Description: A custom test listener extends TestListenerAdapter for take screen shot on failed test case.
    * @author wadexu
    *
    * @updateUser
    * @updateDate 
    */
    public class CustomTestListener extends TestListenerAdapter {
        
        private static String fileSeperator = System.getProperty("file.separator");
        protected static final Logger logger = Logger.getLogger(CustomTestListener.class);
    
        @Override
        public void onTestFailure(ITestResult result) {
            super.onTestFailure(result);
            Object o = result.getInstance();
            WebDriver driver = ((WebDriverHost) o).getWebDriver();
    
            Method method = result.getMethod().getConstructorOrMethod().getMethod();
            TakeScreenshotOnFailure tsc = method.getAnnotation(TakeScreenshotOnFailure.class);
    
            if (tsc != null) {
                String testClassName = getTestClassName(result.getInstance().toString()).trim();
    
                String testMethodName = result.getName().toString().trim();
                String screenShotName = testMethodName + ".png";
    
                if (driver != null) {
                    String imagePath =
                            ".." + fileSeperator + "Screenshots" + fileSeperator + "Results"
                                    + fileSeperator + testClassName + fileSeperator
                                    + takeScreenShot(driver, screenShotName, testClassName);
                    logger.info("Screenshot can be found : " + imagePath);
                }
            }
        }
    
        /**
        * Get screen shot as a file and copy to a new target file
        * 
        * @Title: takeScreenShot
        * @param driver
        * @param screenShotName
        * @param testClassName
        * @return screenShotName
        */
        public static String takeScreenShot(WebDriver driver,
                String screenShotName, String testClassName) {
            try {
                File file = new File("Screenshots" + fileSeperator + "Results");
                if (!file.exists()) {
                    logger.info("File created " + file);
                    file.mkdir();
                }
    
                File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
                File targetFile = new File("Screenshots" + fileSeperator + "Results" + fileSeperator + testClassName, screenShotName);
                FileUtils.copyFile(screenshotFile, targetFile);
    
                return screenShotName;
            } catch (Exception e) {
                logger.error("An exception occured while taking screenshot " + e.getCause());
                return null;
            }
        }
    
        /**
        * Get a test class name
        * 
        * @Title: getTestClassName
        * @param testName
        * @return testClassName
        */
        public String getTestClassName(String testName) {
            String[] reqTestClassname = testName.split("\.");
            int i = reqTestClassname.length - 1;
            String testClassName = reqTestClassname[i].substring(0, reqTestClassname[i].indexOf("@"));
            logger.info("Required Test Name : " + testClassName);
            return testClassName;
        }
    
    }

    接口类 WebDriverHost 

    package test.demo;
    
    import org.openqa.selenium.WebDriver;
    
    /**
     * Class implementing that interface is expected to return instance of web driver used in last test method.
     * 
     * @author wadexu
     */
    public interface WebDriverHost {
    
      /**
       * Returns instance of web driver used in last test method.
       * 
       * @return WebDriver
       */
      public WebDriver getWebDriver();
    }

     ##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html 

    测试基类TestBase

    package test.demo;
    
    import java.io.File;
    import java.io.IOException;
    
    import org.openqa.selenium.WebDriver;
    import org.openqa.selenium.firefox.FirefoxDriver;
    import org.openqa.selenium.firefox.FirefoxProfile;
    import org.testng.annotations.AfterClass;
    import org.testng.annotations.BeforeClass;
    
    /**
     * @Description: Abstract test base class, Test class must extends this class. 
     *               Initialize a firefox webDriver for tutorial purpose only. 
     * @author wadexu
     *
     * @updateUser
     * @updateDate
     */
    public abstract class TestBase implements WebDriverHost{
        
        protected WebDriver webDriver = null;
        
        @Override
        public WebDriver getWebDriver() {
          return webDriver;
        }
        
        @BeforeClass
        public void setUp() throws IOException {
            FirefoxProfile firefoxProfile = new FirefoxProfile();
            // use proxy
            firefoxProfile.setPreference("network.proxy.type", 1);
            firefoxProfile.setPreference("network.proxy.http", "10.51.1.000");
            firefoxProfile.setPreference("network.proxy.http_port", "8080");
    
            //get rid of google analytics, otherwise it's too slow to access to cnblogs website
            firefoxProfile.addExtension(new File(getClass().getClassLoader().getResource("no_google_analytics-0.6-an+fx.xpi").getFile()));
            
            webDriver = new FirefoxDriver(firefoxProfile);
        }
    
        @AfterClass
        public void tearDown() {
            webDriver.close();
        }
        
    }

    DemoListenerTest 测试类

    package test.demo;
    
    import static org.testng.Assert.assertTrue;
    
    import org.testng.annotations.Test;
    
    /**
     * @Description: Demo a Test using custom Test Listener with an annotation TakeScreenshotOnFailure
     * @author wadexu
     * 
     * @updateUser
     * @updateDate
     */
    public class DemoListenerTest extends TestBase{
    
        @Test
        @TakeScreenshotOnFailure
        public void testFail() {
            webDriver.get("http://www.cnblogs.com/");
            
            //Fail this test method for tutorial purpose only
            assertTrue(false);
        }
    
    }

    TestNG 的 xml 文件 配置如下,加入listener监听

    <?xml version="1.0" encoding="UTF-8" ?> 
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
    <!--<suite name="DMP_Test_Suite" -->
    <suite name="Demo_Test_Suite" parallel="false">
        <listeners>
            <listener class-name="test.demo.CustomTestListener" />
        </listeners>
        <test name="Demo_Test">
            <classes>
                <class name="test.demo.DemoListenerTest" />
            </classes>
        </test> 
    </suite>

     ##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html 

    Run as TestNG

    断言故意错误 让test fail

    控制台输出

    2015-10-08 15:04:29,896 INFO [test.demo.CustomTestListener] - Required Test Name : DemoListenerTest
    2015-10-08 15:04:31,985 INFO [test.demo.CustomTestListener] - Screenshot can be found : ..ScreenshotsResultsDemoListenerTest	estFail.png

    图片以测试方法命名, 存在含类名的路径下

    测试方法Pass 或者 fail但没加Annotation 都不会截屏。

    感谢阅读,如果您觉得本文的内容对您的学习有所帮助,您可以点击右下方的推荐按钮,您的鼓励是我创作的动力。

    ##转载注明出处: http://www.cnblogs.com/wade-xu/p/4861024.html 

  • 相关阅读:
    鼠标滑过,解决ul下 li下a的背景与父级Li不同宽的问题
    php函数
    常用函数之数组函数
    php流程控制
    php运算符
    php常量
    php变量的数据类型
    PHP是什么
    css3新增属性
    html5的常用标签
  • 原文地址:https://www.cnblogs.com/wade-xu/p/4861024.html
Copyright © 2011-2022 走看看