查看原文
其他

Java 新特性实例之自动化测试

ImportNew ImportNew 2019-10-02


(给ImportNew加星标,提高Java技能)

编译:ImportNew/唐尤华

angiejones.tech/new-java-features-test-automation/


Java 8 开始引入了许多很酷的新特性。实际上,Java 每6个月就会发布一个新版本!这么多新功能,很难跟上更新的脚步。


这些新特性旨在改进 Java 代码冗长的问题,具体方法就是减少样板代码。


下面是自动化测试中用到的 Java 8 至 Java 12 一些新特性,通过 Todo 示例应用展示。


1. 创建集合


Java 9 为ListSetMap 这样的集合类加入了 of() 静态工厂方法,让创建列表变得更容易。


在 Java 9 之前,要创建任务列表 tasks 可以这样做:


List<String> tasks = Arrays.asList("pay mortgage bill", "make dentist appointment", "get car washed");


这段代码看起来并不可怕,比起创建 List 对象然后循环调用 add() 方法已经改进了不少。


然而,Java 9 可以用 List.of()。不仅可读性更强,依赖的 import 更少,而且更容易记住:

List<String> tasks = List.of("pay mortgage bill", "make dentist appointment", "get car washed");


使用 of() 创建集合的一个缺点,创建的集合不可变。这意味着集合创建后不能添加、删除或者排序。


2. 局部变量类型推断


Java 代码冗长其中一个原因是需要显式声明变量或者对象类型。当类型包含范型操作符 <> 或者类名很长时,代码看起来很枯燥。


Java 10 引入了局部变量类型推断,用 var 声明变量。使用 var 必须在声明的时候初始化变量,因为 Java 需要根据赋值语句进行类型推断。


例如,可以用 var 替代 List<String> 声明 tasks。由于使用 List.of() 建立字符串列表并赋值,Java 知道 tasks 的类型是 List<String>


var tasks = List.of( "pay mortgage bill", "make dentist appointment", "get car washed");


我非常钟爱 var,这是我最喜欢的 Java 新特性。写 Java 代码从此不再枯燥。尽管如此,还是会提醒自己不要得意忘形,代码的可读性依然很重要。如果程序员自己都不能根据赋值语句判断出类型,那么最好还是直接写上变量类型,让代码变得更清晰易懂。


3. 函数式编程新特性


Java 8 加入了许多函数式编程新特性,比如 lambda 表达式。在集合框架中新加入的 forEach() 方法中可以使用。


在此之前,可以使用传统的 for 循环在 Todo 应用中添加 task


var tasks = List.of("pay mortgage bill", "make dentist appointment", "get car washed");
for(int i=0; i<tasks.size(); i++){
todosPage.addTask(tasks.get(i));
}


也可以使用改进版 for 循环,看起来简洁了一点:


var tasks = List.of("pay mortgage bill", "make dentist appointment", "get car washed");
for(String task: tasks){
todosPage.addTask(task);
}


Java 8 中的 forEach() 支持函数式编程,遍历集合更简洁。可以像下面这样遍历 list


tasks.forEach(


forEach() 方法内部可以写一个 lambda 表达式。


lambda 表达式以当前集合元素名task开始,变量可以使用1个字母的短名。由于是局部 final 变量,因此不能在方法外使用。实际开发中会使用t,这里使用了全名。

tasks.forEach(task


接着是 -> 操作符与在元素上执行的操作:


tasks.forEach(task -> todosPage.addTask(task));


实际上,这里只有1个变量与1个待执行的操作。可以用 object::method 方式来缩短表达式,不用为列表的每个元素声明局部变量,同样的代码可以更简洁:


tasks.forEach(todosPage::addTask);


然而,如果需要对集合中的项目执行多个操作,可以直接在 -> 后面使用大括号


tasks.forEach(task -> {
todosPage.addTask(task);
//TODO: 在 task 上执行更多操作
});


所以,就上面的例子来说,最终代码如下:


var tasks = List.of("pay mortgage bill","make dentist appointment","get car washed");
tasks.forEach(todosPage::addTask);


4. Stream


添加任务后,接下要进行验证。看看如何获取所有 task


Java 8 之前,需要编写代码查找所有 WebElement 对象,然后循环遍历获取每个 task 的文本。迭代过程中,需要将 String 添加到一个新列表然后返回:


public List<String> getAllTasks(){
List<WebElement> elementList = driver.findElements(tasksLocator);
List<String> taskList = new ArrayList();
for(WebElement element : elementList){
taskList.add(element.getText());
}
return taskList;
}


这段代码相当冗长了。幸运的是 Java 8 引入了 Stream,处理集合数据变得更简单。


为 WebDriver 的 findElements() 返回的 Web 元素调用 stream() 方法:


driver.findElements(tasksLocator).stream()


Stream 提供了许多方法可供选择,这里使用 map() 对集合中的每个元素执行函数,即从元素获取文本,例如 WebElement.getText()


driver.findElements(tasksLocator).stream().map(WebElement::getText)


上面的代码会返回应用函数后的结果 Stream,其中包含了针对每个元素调用 WebElement.getText() 后的 String 值。


这里希望返回 String 列表,因此调用 collect()


public List<String> getAllTasks(){
return driver.findElements(tasksLocator).stream().map(WebElement::getText).collect(Collectors.toList());
}


可以看到,比起之前的方法代码精简了许多。


5. switch 表达式


Java 12 引入了一种 switch 新用法。


比如,在代码中进行 API 调用。Java 12 之前,我们会使用 switch 语句决定调用哪个 API


public static Response execute(String endpoint, HttpMethod method){
Response response = null;
switch(method){
case GET:
response = request.get(endpoint);
break;
case POST:
response = request.post(endpoint);
break;
}
response.then().log().all();
return response;
}


每种情况下,都需要执行一个赋值操作,同时带上一个 break 语句。


有了 Java 12 带来的 switch 新用法,可以大大简化代码,可以根据 switch 处理的结果直接为变量赋值。


以上面的代码为例,可以将每个表达式赋值给 response switch 内部,把 : 换成 -> 不需要原来的 break default 语句:


public static Response execute(String endpoint, HttpMethod method){
Response response = switch(method){
case GET -> request.get(endpoint);
case POST -> request.post(endpoint);
}
response.then().log().all();
return response;
}


完整源代码在 GitHub 上

github.com/angiejones/new-java-features-test-automation


推荐阅读

(点击标题可跳转阅读)

如何访问 redis 中的海量数据?避免事故产生

用了这么久 IDEA ,你竟然不知道有个功能叫自动补全!

10 张 GIF 动图让你弄懂递归等概念


看完本文有收获?请转发分享给更多人

关注「ImportNew」,提升Java技能

好文章,我在看❤️

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存