View on GitHub

spring-boot-in-action

Spring Boot 实战笔记

测试运行中的应用程序

在真实的服务器里启动应用程序,用真实 的Web浏览器访问它,这样比使用模拟的测试引擎更能展现应用程序在用户端的行为。

Spring Boot 支持将 Tomcat 或 Jetty 这样的嵌入式Servlet容器作为运行 中的应用程序的一部分,可以运用相同的机制,在测试过程中用嵌入式Servlet容器来启动应用 程序。

添加注解

在测试类上添加 @WebIntegrationTest 注解,可以声明你不仅希望Spring Boot为测试创建应用程序上下文,还要启动一个嵌入式的Servlet容器。

一旦应用程序运行在嵌入式容器里,就可以发起真实的HTTP请求,断言结果了。

Spring-Boot-1.4 版本之后,需要添加以替代 @WebIntegrationTest

@SpringBootTest(webEnvironment=WebEnvironment.DEFINED_PORT)

测试运行,使用了Spring的 RestTemplate 对一个不存在的页面发起请求:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ReadingListApplication.class, webEnvironment=WebEnvironment.DEFINED_PORT)
public class SimpleWebTest {
    
    @Test(expected = ResourceAccessException.class)
    public void pageNotFound() {
        try {
            RestTemplate rest = new RestTemplate();
            rest.getForObject("http://localhost:8080/bogusPage", String.class);
            fail("Should result in HTTP 404");
        } catch (ResourceAccessException e) {
            throw e;
        }
    }

}

用随机端口启动服务器

让Spring Boot在随机选择的端口上启动服务器:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

随机使用端口后,以实例变量的形式注入选中的端口:

@Value("${local.server.port}")
private int port;

使用 Selenium 测试 HTML 页面

Selenium 能实际打开一个Web浏览器,在浏览器的上下文中执行测试。

Selenium尽量接近手动执行测试,但与手工测试不同。Selenium的测试是自动的,而且可以重复运行。

在 maven 项目中加入 Selenium 依赖 最新版本

<dependency>
	<groupId>org.seleniumhq.selenium</groupId>
	<artifactId>selenium-java</artifactId>
	<version>3.141.59</version>
</dependency>

在Spring Boot里使用Selenium测试的模板:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ReadingListApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)    // 用随机端口启动
public class SimpleWebTest {

    private static ChromeDriver browser;

    @Value("${local.server.port}")  // 注入端口号
    private int port;

    @BeforeClass
    public static void openBrowser() {
        // 加载 Chrome 驱动
        System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
        ChromeOptions chromeOptions = new ChromeOptions();
        chromeOptions.addArguments("--headless");   // 自动化不打开浏览器测试
        browser = new ChromeDriver(chromeOptions); // 配置 Chrome 驱动
        browser.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);  
    }
    
    @AfterClass
    public static void closeBrowser() {
        browser.quit(); // 关闭浏览器
    }
}

用 Selenium 测试阅读列表应用程序:

@Test
public void addBookToEmptyList() {
    // 加载首页
    String baseUrl = "https://localhost:" + port;
    browser.get(baseUrl);
    // 登录验证并发送表单
    browser.findElementByName("username").sendKeys("craig");
    browser.findElementByName("password").sendKeys("password");
    browser.findElementByTagName("form").submit();
    // 填充书籍信息并发送表单
    assertEquals("You have no books in your book list", browser.findElementByTagName("div").getText());
    browser.findElementByName("title").sendKeys("BOOK TITLE");
    browser.findElementByName("author").sendKeys("BOOK AUTHOR");
    browser.findElementByName("isbn").sendKeys("1234567890");
    browser.findElementByName("description").sendKeys("DESCRIPTION");
    browser.findElementById("addbookform").submit();
    // 判断登录的页面是否包含刚刚添加的新书
    WebElement dl = browser.findElementByCssSelector("dt.bookHeadline");
    assertEquals("BOOK TITLE by BOOK AUTHOR (ISBN: 1234567890)", dl.getText());
    WebElement dt = browser.findElementByCssSelector("dd.bookDescription");
    assertEquals("DESCRIPTION", dt.getText());
}

测试代码

SimpleWebTest 类