一、前言
对于任何软件来说,构建自动化测试方案是非常有用,Gradle 作为基于 JVM 的构建工具,兼顾灵活性和高性能,有着约定优于配置的方法、强大的依赖管理,它的构建脚本使用 Groovy 或 Kotlin 编写,是Android的官方构建工具,而在本文要探讨的就是 Groovy 语言。
二、Groovy 简介
Groovy 是 Apache 旗下的一种基于 Jvm 的面向对象编程语言,既可以用于面向对象编程,也可以用作纯粹的脚本语言。它在兼容Java语法的同时,借鉴了 Ruby、Python 等语言的特性,比如动态类型转换、闭包和元编程支持等。同时,运行在 JVM 上也意味着它也可以使用Java语言编写的库。比如在写 Groovy 的时候忘记了语法可以直接按 Java 的语法继续写,也可以在 Java 中调用 Groovy 脚本。比起Java,Groovy 语法更加的灵活和简洁,同样的功能 Groovy 代码量更少。这就使得 Groovy 极其适合编写 Java 代码的测试脚本。
二、安装环境
在 Groovy官网 上下载二进制的安装包,这里以 4.0.21 版本为例:
1、 解压并移动到指定目录下
mv groovy-4.0.21/ ~/source/bin/ |
2、配置环境变量
$ vim ~/.bashrc |
3、校验
$ which groovy |
至此环境安装完成
三、从 Hello World 开始
首先要说明的是在 Groovy 中完全兼容 Java 语法,因此在任何要使用 Groovy 的地方都可以直接使用 Java 来实现!,因此在本文中主要介绍 Groovy 有别于 Java 的地方。
3.1 输出特性
先来看一下 Groovy 输出方式:
1. print xxx //同一行输出 |
Groovy 中输出语句不依靠类和函数,即可以不定义在类和函数内部。这里借由 Hello World 的两种示例来展示 Groovy 的特性:
1、方式一:
新建 HelloWorld.groovy 文件,写入一下代码:
static main(args){ |
2、方式二:
println "Hello World!" |
使用 groovy 来执行这个脚本,会得到相同的结果:
$ groovy HelloWorld.groovy |
3.2 变量及类型
3.2.1 变量类型
Groovy 中数据类型在完全支持 Java 的同时又扩展了其他的几种类型如下:
类型 | 类型 |
---|---|
allprojects | 包含此项目及其子项目的集合 |
ant | 此项目的AntBuilder,可以在构建文件中使用它来执行 ant 任务 |
long | BigInteger |
float | double |
BigDecimal | boolean |
3.2.2 Groovy 中变量声明方式:
- 显式声明: 明确变量的数据类型,如: int age = 18;
- 隐式声明: 不明变量的数据类型,如: def age = 18;
Groovy 中用 def 关键字来定义变量,可以不指定变量的类型,groovy 会根据变量的值自动赋予变量类型,默认访问修饰符是 public :
def number = 1 |
3.2.3 集合类型
Groovy 没有定义自己的集合类,它在 Java 集合类的基础上进行了增强和简化。Groovy 的 List 对应Java中的 List 接口,默认的实现类为 Java 中的 ArrayList:
def number = [1, 2, 3] |
可以使用 as 操作符来显式指定 List 的实现类为 java.util.LinkedList。
获取元素同样要比 Java 要简洁些,使用 [] 来获取 List 中具有正索引或负索引的元素,使用 remove 方法来删除元素。
def number = [1, 2, 3, 4] |
注释 ①处的索引 -1 是列表末尾的第一个元素。注释 ② 处使用 << 运算符在列表末尾追加一个元素。
3.2.4 Map 类型
Groovy 的 map 对象就是 Java 中的 LinkedHashMap,使用 [] 定义一个 map,map 中的 key、value 对使用逗号分隔。可以使用 [] 取出 key 对应的 value,也能使用 . 取出 value,添加 map 的键值对,使用 put 方法或者 <<。
def map = [red: 1, green:2] |
Map 的键关联问题:
def key = 'red' |
注释 ① 处的键值是 key 这个字符串,而不是key变量的值 red 。如果想要以 key 变量的值为键值,需要像注释 ② 处一样使用 (key),用来告诉解析器我们传递的是一个变量,而不是定义一个字符串键值。
3.3 语句
3.3.1 断言
//使用断言时,应包含一条消息。此消息可以帮助其他人维护和理解你的代码,理清你的意图。 |
3.3.2 for循环
Groovy 支持 Java 的 for(int i=0;i<N;i++) 和 for(int i : array) 形式的循环语句,另外还支持 for in loop 形式,支持遍历范围、列表、Map、数组和字符串等多种类型
//遍历范围 |
3.3.3 switch语句
Groovy 中的 Switch 在兼容 Java 原有的方式上,又扩展了新的特性,即可以处理更多类型的表达式,如字符串、列表、范围、Integer等等
def x = 16 |
3.3.4 字符串
- 普通字符串 String
// 单引号字符串 |
- 可变字符串 GString
String 是不可变的,GString 却是可变的,GString 和 String 即使有相同的字面量,它们的 hashCodes 的值也可能不同,因此应该避免使用使用 GString 作为 Map 的 key,简而言之:当双引号字符串中包含插值表达式时,字符串类型为GString
3.4 闭包
Groovy 中的闭包是一个开放的、匿名的、可以接受参数和返回值的代码块,同样闭包可以作为对象、参数和返回值给其他地方使用,闭包的定义遵循以下语法:
{ [ closureParameters -> ] statements } |
参数列表部分是可选的,如果闭包只有一个参数,参数名是可选的,Groovy 会隐式指定 it 作为参数名,示例如下:
// 一个参数 |
闭包调用:
def code = { 123 } |
3.5 方法
在兼容 Java 原有的定义方法的基础上,扩展了使用 def 关键字来定义方法,这种形式下方法可以接收任意数量的参数,这些参数可以不申明类型,如果不提供可见性修饰符,则该方法为 public。
def add(int a,int b) { |
从上面两段代码中可以发现 Groovy 中有很多省略的地方:
- 语句后面的分号可以省略。
- 方法的括号可以省略,比如注释 ⑤ 处。
- 参数类型可以省略,比如注释 ② 处。
- return可以省略掉,比如注释 ④处。
3.6 类
Groovy 类与 Java 类有以下的区别:
- 默认类的修饰符为 public。
- 没有可见性修饰符的字段会自动生成对应的 setter 和 getter 方法。
- 类不需要与它的源文件有相同的名称,但还是建议采用相同的名称。
class Person { |
3.7 元编程
元对象编程可用于动态调用方法,即可以即时创建类和方法,如下 Student 类,使用 MetaClass 来实现一些有意思的事:
|
3.8 IO操作
- 文件读取
def filePath = "D:/Android/name.txt" |
- 文件写入
def filePath = "D:/Android/name.txt" |
3.9 其他
- 安全取值
println school?.student?.name |
- with 操作符
|
- asType 数据类型转换
String a = '23' |
3.10 语法糖
语法糖。所谓语法糖就相当于汉语里的成语。即,用更简练的言语表达较复杂的含义。在得到广泛接受的情况之下,可以提升交流的效率。上面所介绍的各种简单易用的书写形式就是语法糖。