使用ImageMagick和Selenium Webdriver进行自动化视觉测试

Posted 京鸿智武

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用ImageMagick和Selenium Webdriver进行自动化视觉测试相关的知识,希望对你有一定的参考价值。

在本文中,我将向您介绍如何使用ImageMagickSelenium WebdriverAShot进行视觉测试自动化。这个工具和框架组合是完全开源的,当您成功完成设置时,您可以开始无需任何费用就可以对它们进行可视化测试。

首先,我想描述这些工具:

Selenium Webdriver我们将使用webdriver导航,查询和操作网站。

ImageMagick ImageMagick是我们的图像处理和比较工具。

链接http//www.imagemagick.org/script/index.php

JAVA界面(im4javahttp : //im4java.sourceforge.net/

AShot AShot是我们的Webdriver Screenshot实用工具。我们将使用AShot截图截图。它由 Yandex及其开源开发

链接https//github.com/yandex-qatools/ashot

逐步安装

 步骤1Selenium Webdriver

 如果您不知道如何开始使用Selenium Webdriver,请先阅读本文

 2步:Visual Studio 2013Visual C ++可再发行组件包

 转到此链接:https : //www.microsoft.com/en-us/download/details.aspx?id=40784并安装它。

 使用ImageMagick和Selenium Webdriver进行自动化视觉测试使用ImageMagick和Selenium Webdriver进行自动化视觉测试

使用ImageMagick和Selenium Webdriver进行自动化视觉测试


3步:ImageMagick

 转至http://www.imagemagick.org/script/binary-releases.php安装Windows Binary Release,在安装期间选择所有选项并将其安装目录位置设置为系统路径

选择所有选项非常重要。

 

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

使用ImageMagick和Selenium Webdriver进行自动化视觉测试


使用ImageMagick和Selenium Webdriver进行自动化视觉测试

如何为ImageMagickSelenium设置项目

测试场景:

- 打开www.kariyer.net

- 添加顶部横幅Cookie不看顶部横幅。

- 如果存在,关闭弹出窗口

- 关闭横幅

- 取消隐藏Uzman Photo的文字区域(“ 21.923İİİII”部分)

- 悬停在主页上的“UZMAN”部分。

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

- 等待2秒钟完成图像(CSS)动画。

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

- 截取此元素的动画照片。

- 在第一次运行时,将它保存到ScreenShots> $ Test_Name文件夹中作为uzmanBaseline.pnguzmanActual.png

- 第二次运行时,更新uzmanActual.png,并将其与uzmanBaseline.png进行比较,并将差异作为uzmanDiff.png

- 把所有的差异放在差异文件夹中。

- 验证他们是否通过了类似的测试。如果没有测试失败。

项目设置:

打开IntelliJ,然后点击文件 - >新建 - >项目 - > Maven

然后,将GroupIdArtifactId填充为KariyerVisualTest

使用ImageMagick和Selenium Webdriver进行自动化视觉测试单击下一步,然后为该项目命名为KariyerVisualTest,然后单击下一步。

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

之后,我们应该修改我们的pom.xml

始终从https://mvnrepository.com检查库最新版本

对于硒:

Xhtml

1

2

3

4

5

<dependency>

    <groupId>org.seleniumhq.selenium</groupId>

    <artifactId>selenium-java</artifactId>

    <version>3.0.1</version>

</dependency>

对于AShot

XHTML

1

2

3

4

5

<dependency>

    <groupId>ru.yandex.qatools.ashot</groupId>

    <artifactId>ashot</artifactId>

    <version>1.5.3</version>

</dependency>

对于IM4Java

XHTML

1

2

3

4

5

<dependency>

    <groupId>org.im4java</groupId>

    <artifactId>im4java</artifactId>

    <version>1.4.0</version>

</dependency>

对于TestNG

XHTML

1

2

3

4

5

<dependency>

    <groupId>org.testng</groupId>

    <artifactId>testng</artifactId>

    <version>6.10</version>

</dependency>

测试代码

在下面的代码中,我尝试写出详细的评论。如果您遇到麻烦,请随时添加评论。我会尽快回复你的问题。

BaseTest

KariyerVisualTest .java

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

import com.google.common.io.Files;

import org.apache.commons.io.FileUtils;

import org.im4java.core.CompareCmd;

import org.im4java.core.IMOperation;

import org.im4java.process.ProcessStarter;

import org.im4java.process.StandardStream;

import org.openqa.selenium.*;

import org.openqa.selenium.chrome.ChromeDriver;

import org.openqa.selenium.interactions.Actions;

import org.openqa.selenium.support.ui.WebDriverWait;

import org.testng.annotations.BeforeClass;

import org.testng.annotations.BeforeMethod;

import ru.yandex.qatools.ashot.AShot;

import ru.yandex.qatools.ashot.Screenshot;

 

import javax.imageio.ImageIO;

import java.io.File;

import java.io.IOException;

import java.lang.reflect.Method;

import java.util.Calendar;

import java.util.Date;

import java.util.List;

 

/**

 * Created by onurb on 06-Feb-17.

 */

public class BaseTest {

 

    public WebDriver driver;

    public WebDriverWait wait;

    public javascriptExecutor js;

 

    //JSWaiter object

    JSWaiter jsWaiter;

 

    //Test name

    public String testName;

 

    //Test Screenshot directory

    public String testScreenShotDirectory;

 

    //URL of the test website

    public String url = "http://www.kariyer.net";

 

    //Main Directory of the test code

    public String currentDir = System.getProperty("user.dir");

 

    //Main screenshot directory

    public String parentScreenShotsLocation = currentDir + "\\ScreenShots\\";

 

    //Main differences directory

    public String parentDifferencesLocation = currentDir + "\\Differences\\";

 

    //Element screenshot paths

    public String baselineScreenShotPath;

    public String actualScreenShotPath;

    public String differenceScreenShotPath;

 

    //Image files

    public File baselineImageFile;

    public File actualImageFile;

    public File differenceImageFile;

    public File differenceFileForParent;

 

    //Setup Driver

    @BeforeClass

    public void setupTestClass() throws IOException {

        //Declare Firefox driver

        driver = new ChromeDriver();

 

        //Maximize the browser

        driver.manage().window().maximize();

 

        //Declare a 10 seconds wait time

        wait = new WebDriverWait(driver,10);

 

        //JS Executor

        js = (JavascriptExecutor) driver;

 

        //JSWaiter

        jsWaiter = new JSWaiter(wait);

 

        //Create screenshot and differences folders if they are not exist

        createFolder(parentScreenShotsLocation);

        createFolder(parentDifferencesLocation);

 

        //Clean Differences Root Folder

        File differencesFolder = new File(parentDifferencesLocation);

        FileUtils.cleanDirectory(differencesFolder);

 

        //Go to URL

        driver.navigate().to(url);

 

        //Add Cookie for top banner

        addCookieforTopBanner();

    }

 

    @BeforeMethod

    public void setupTestMethod (Method method) {

        //Get the test name to create a specific screenshot folder for each test.

        testName = method.getName();

        System.out.println("Test Name: " + testName + "\n");

 

        //Create a specific directory for a test

        testScreenShotDirectory = parentScreenShotsLocation + testName + "\\";

        createFolder(testScreenShotDirectory);

 

        //Declare element screenshot paths

        //Concatenate with the test name.

        declareScreenShotPaths(testName+"_Baseline.png", testName+"_Actual.png", testName + "_Diff.png");

    }

 

    //Add Cookie not to see top banner animation

    public void addCookieforTopBanner () {

        //Get Next Month Last Date for cookie expiration

        Calendar calendar = Calendar.getInstance();

        calendar.add(Calendar.MONTH, 1);

        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));

        Date nextMonthLastDay = calendar.getTime();

 

        //Create/Build a cookie

        Cookie topBannerCloseCookie = new Cookie.Builder("AA-kobiBannerClosed","4") //Name & value pair of the cookie

                .domain("www.kariyer.net") //Domain of the cookie

                .path("/") //Path of the cookie

                .expiresOn(nextMonthLastDay) //Expiration date

                .build(); //Finally build it with .build() call

 

        //Add a cookie

        driver.manage().addCookie(topBannerCloseCookie);

    }

 

    //Create Folder Method

    public void createFolder (String path) {

        File testDirectory = new File(path);

        if (!testDirectory.exists()) {

            if (testDirectory.mkdir()) {

                System.out.println("Directory: " + path + " is created!" );

            } else {

                System.out.println("Failed to create directory: " + path);

            }

        } else {

            System.out.println("Directory already exists: " + path);

        }

    }

 

    //Close popup if exists

    public void handlePopup(String selector) throws InterruptedException {

        jsWaiter.waitJS();

        List<WebElement> popup = driver.findElements(By.cssSelector(selector));

        if(!popup.isEmpty()){

            popup.get(0).click();

            sleep(200);

        }

    }

 

    //Close Banner

    public void closeBanner () {

        jsWaiter.waitJS();

        List<WebElement> banner = driver.findElements(By.cssSelector("body > div.kobi-head-banner > div > a"));

        if (!banner.isEmpty()) {

            banner.get(0).click();

            //Wait for 2 second for closing banner

            sleep(2000);

        }

    }

 

    //Unhide an Element with JSExecutor

    public void unhideElement (String unhideJS) {

        js.executeScript(unhideJS);

        jsWaiter.waitJS();

        sleep(200);

    }

 

    //Move to Operation

    public void moveToElement (WebElement element){

        jsWaiter.waitJS();

        Actions actions = new Actions(driver);

        jsWaiter.waitJS();

        sleep(200);

        actions.moveToElement(element).build().perform();

    }

 

    //Take Screenshot with AShot

    public Screenshot takeScreenshot (WebElement element) {

        //Take screenshot with Ashot

        Screenshot elementScreenShot = new AShot().takeScreenshot(driver, element);

        /*Screenshot elementScreenShot = new AShot()

                .coordsProvider(new WebDriverCoordsProvider())

                .takeScreenshot(driver,element);*/

 

        //Print element size

        String size = "Height: " + elementScreenShot.getImage().getHeight() + "\n" +

                "Width: " + elementScreenShot.getImage().getWidth() + "\n";

        System.out.print("Size: " + size);

 

        return elementScreenShot;

    }

 

    //Write

    public void writeScreenshotToFolder (Screenshot screenshot, File imageFile) throws IOException {

        ImageIO.write(screenshot.getImage(), "PNG", imageFile);

    }

 

    //Screenshot paths

    public void declareScreenShotPaths (String baseline, String actual, String diff) {

        //BaseLine, Actual, Difference Photo Paths

        baselineScreenShotPath = testScreenShotDirectory + baseline;

        actualScreenShotPath = testScreenShotDirectory + actual;

        differenceScreenShotPath = testScreenShotDirectory + diff;

 

        //BaseLine, Actual Photo Files

        baselineImageFile = new File(baselineScreenShotPath);

        actualImageFile = new File(actualScreenShotPath);

        differenceImageFile = new File (differenceScreenShotPath);

 

        //For copying difference to the parent Difference Folder

        differenceFileForParent = new File (parentDifferencesLocation + diff);

    }

 

    //ImageMagick Compare Method

    public void compareImagesWithImageMagick (String expected, String actual, String difference) throws Exception {

        // This class implements the processing of os-commands using a ProcessBuilder.

        // This is the core class of the im4java-library where all the magic takes place.

        ProcessStarter.setGlobalSearchPath("C:\\Program Files\\ImageMagick-7.0.4-Q16");

 

        // This instance wraps the compare command

        CompareCmd compare = new CompareCmd();

 

        // Set the ErrorConsumer for the stderr of the ProcessStarter.

        compare.setErrorConsumer(StandardStream.STDERR);

 

        // Create ImageMagick Operation Object

        IMOperation cmpOp = new IMOperation();

 

        //Add option -fuzz to the ImageMagick commandline

        //With Fuzz we can ignore small changes

        cmpOp.fuzz(10.0);

 

        //The special "-metric" setting of 'AE' (short for "Absolute Error" count), will report (to standard error),

        //a count of the actual number of pixels that were masked, at the current fuzz factor.

        cmpOp.metric("AE");

 

        // Add the expected image

        cmpOp.addImage(expected);

 

        // Add the actual image

        cmpOp.addImage(actual);

 

        // This stores the difference

        cmpOp.addImage(difference);

 

        try {

            //Do the compare

            System.out.println ("Comparison Started!");

            compare.run(cmpOp);

            System.out.println ("Comparison Finished!");

        }

        catch (Exception ex) {

            System.out.print(ex);

            System.out.println ("Comparison Failed!");

            //Put the difference image to the global differences folder

            Files.copy(differenceImageFile,differenceFileForParent);

            throw ex;

        }

    }

 

    //Compare Operation

    public void doComparison (Screenshot elementScreenShot) throws Exception {

        //Did we capture baseline image before?

        if (baselineImageFile.exists()){

            //Compare screenshot with baseline

            System.out.println("Comparison method will be called!\n");

 

            System.out.println("Baseline: " + baselineScreenShotPath + "\n" +

                    "Actual: " + actualScreenShotPath + "\n" +

                    "Diff: " + differenceScreenShotPath);

 

            //Try to use IM4Java for comparison

            compareImagesWithImageMagick(baselineScreenShotPath, actualScreenShotPath, differenceScreenShotPath);

        } else {

            System.out.println("BaselineScreenshot is not exist! We put it into test screenshot folder.\n");

            //Put the screenshot to the specified folder

            ImageIO.write(elementScreenShot.getImage(), "PNG", baselineImageFile);

        }

    }

 

    //Sleep Function

    public void sleep (int milis) {

        Long milliseconds = (long) milis;

        try {

            Thread.sleep(milliseconds);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

    }

    

}

JSWaiter(用于JSJQuery同步)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

import org.openqa.selenium.JavascriptExecutor;

import org.openqa.selenium.support.ui.ExpectedCondition;

import org.openqa.selenium.support.ui.WebDriverWait;

 

/**

 * Created by onurb on 06-Feb-17.

 */

public class JSWaiter {

 

    public WebDriverWait wait;

 

    public JSWaiter (WebDriverWait wait) {

        this.wait = wait;

    }

 

    public void waitJS () {

        //Wait for Javascript to load

        ExpectedCondition<Boolean> jsLoad = driver -> ((JavascriptExecutor) driver)

                .executeScript("return document.readyState").toString().equals("complete");

 

 

        //JQuery Wait

        ExpectedCondition<Boolean> jQueryLoad = driver -> ((Long) ((JavascriptExecutor) driver)

                .executeScript("return jQuery.active") == 0);

 

        wait.until(jsLoad);

        wait.until(jQueryLoad);

    }

}

KariyerVisualTest(测试类)

KariyerVisualTest.java

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

import org.openqa.selenium.By;

import org.openqa.selenium.WebElement;

import org.testng.annotations.AfterClass;

import org.testng.annotations.Test;

import ru.yandex.qatools.ashot.Screenshot;

 

/**

 * Created by onurb on 28-Aug-16.

 */

public class KariyerVisualTest extends BaseTest {

 

    @Test

    public void kariyerUzmanCssTest () throws Exception {

        //Handle popup

        handlePopup(".ui-dialog-titlebar-close");

 

        //Close banner

        closeBanner();

 

        //Declare UZMAN photo section

        WebElement uzmanPhotoSection = driver.findElement(By.cssSelector(".item.uzman>a"));

 

        //Unhide Text (It is Changing A lot)

        unhideElement("document.getElementsByClassName('count')[0].style.display='none';");

 

        //Move To Operation

        moveToElement(uzmanPhotoSection);

 

        //Wait for 2 second for violet color animation

        Thread.sleep(2000);

 

        //Take ScreenShot with AShot

        Screenshot uzmanScreenShot = takeScreenshot(uzmanPhotoSection);

 

        //Write actual screenshot to the actual screenshot path

        writeScreenshotToFolder(uzmanScreenShot, actualImageFile);

 

        //Do image comparison

        doComparison(uzmanScreenShot);

    }

 

    //Close Driver

    @AfterClass

    public void quitDriver() {

        driver.quit();

    }

}

pom.xml中:

pom.xml

XHTML

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

 

    <groupId>KariyerVisualTest</groupId>

    <artifactId>KariyerVisualTest</artifactId>

    <version>1.0-SNAPSHOT</version>

    <build>

        <plugins>

            <plugin>

                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>

                <configuration>

                    <source>1.8</source>

                    <target>1.8</target>

                </configuration>

            </plugin>

        </plugins>

    </build>

 

    <dependencies>

 

        <dependency>

            <groupId>org.seleniumhq.selenium</groupId>

            <artifactId>selenium-java</artifactId>

            <version>3.0.1</version>

        </dependency>

 

        <dependency>

            <groupId>org.testng</groupId>

            <artifactId>testng</artifactId>

            <version>6.10</version>

        </dependency>

 

        <dependency>

            <groupId>org.im4java</groupId>

            <artifactId>im4java</artifactId>

            <version>1.4.0</version>

        </dependency>

 

        <dependency>

            <groupId>ru.yandex.qatools.ashot</groupId>

            <artifactId>ashot</artifactId>

            <version>1.5.3</version>

        </dependency>

 

        <dependency>

            <groupId>commons-io</groupId>

            <artifactId>commons-io</artifactId>

            <version>2.5</version>

        </dependency>

 

 

    </dependencies>

 

</project>

testng.xml

testNG.xml

XHTML

1

2

3

4

5

6

7

8

9

10

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

 

<suite name="Kariyer Visual Automation with IM4JAVA Selenium AShot">

    <test name="RunTest" preserve-order="true">

        <classes>

            <class name="KariyerVisualTest" />

        </classes>

    </test>

</suite>

GitHub链接https://github.com/swtestacademy/VisualAutomationImageMagickSelenium

检测结果:

 第一次运行: 使用ImageMagick和Selenium Webdriver进行自动化视觉测试使用ImageMagick和Selenium Webdriver进行自动化视觉测试 

二次运行(正面情况): 

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

使用ImageMagick和Selenium Webdriver进行自动化视觉测试

 

第三轮(负面情况):

 我也想告诉你失败的案例。我用照片编辑器打开uzmanBaseline并添加一些形状并保存。之后,我重新运行测试,并得到了低于结果。测试失败,并突出显示了无与伦比的部分。

在开始测试之前,我对“uzmanBasline.png”进行了以下修改

使用ImageMagick和Selenium Webdriver进行自动化视觉测试


然后,我运行测试并得到以下结果: 使用ImageMagick和Selenium Webdriver进行自动化视觉测试

网址:www.kingoftech.cn


以上是关于使用ImageMagick和Selenium Webdriver进行自动化视觉测试的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Selenium 和 Python 从 <select> 中选择任何 <options>

selenium环境搭建,driver方法简述

Selenium 无法正常工作 Mac [重复]

TestNG,Selenium 如何在多个类之间共享对象

Imagemagick、雪豹和 PDF 转换

爬虫入门Selenium用法简介