文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

在Stormpath(译者注:一款用户管理和认证服务软件,也是该软件的公司名),我们把质量和生产力看得非常重要。每一个优秀的工匠都知道,要完成工作,仅仅拥有天赋是不够的,还需要有正确的工具。工程学不仅仅是一门科学,还是一门艺术,因此虽然我们Stormpath的员工都毋庸置疑地都很有天赋(眨眼眨眼(译者注:调皮的样子)), 我们还是在一直不断的寻找最适合我们需求的工具。我们的工程师总是渴望跟其他团队成员分享新的工具。而现在,我们将要向所有其他有天赋的Java开发者们推荐这些工具!

在这篇文章中,我将会分享一下我们的Java SDK团队每天工作中所使用到的工具以及我们是如何使用的,并且希望能够分享一些有用的技巧给大家。

第 1 段(可获 1.53 积分)

1. Groovy

我们不用Java书写测试代码,而是使用Groovy。为什么? 因为它免费提供了以下这些功能:

轻松的类似Java的语法:是Java的语法,但是规则更少些。例如,分号、变量类型和访问修饰符都是可选的。这样对于测试来说就有很大的优势。由于访问修饰符并非严格的,你的测试就可以读取被测类的内部状态并进行断言。比如,设想一下,你有如下这个类:

public class Foo {
    private String bar = null;
    public void setBar(String bar) {
        this.bar = bar;
    }
}
第 2 段(可获 1.01 积分)

如果你想测试setBar(String)方法确保它正常工作(也就是说它能够正确的将private属性bar的值修改掉),你就可以通过使用Groovy读取该变量的值来简单的完成该任务。Java就不会允许这种事情发生(除非借助于反射)。

@Test     
public void test() {
    def foo = new Foo()
    foo.setBar("hello")
    Assert.isTrue(foo.bar.equals("hello"))
    //groovy allows us to access the private property called bar
}

Power AssertionsGroovy 提供了一个强大的assert的变体,被称为power assertion语句。Groovy的power assert可以在验证失败的时候清楚的告诉我们结果是什么。 而且它比Java对应的语句要更具可读性。

第 3 段(可获 1.03 积分)
Assert.isTrue(foo.bar.equals("hello")) 

这段代码可以翻译成:

assert foo.bar == "hello"

当断言失败时,它会给我们展示一段能够清晰描述发生的事情的描述文本

assert foo.bar == "goodbye"
       |   |   |
       |   |   false
       |   hello
       Foo@12f41634 

Mocking:当使用Java的时候,动态模拟框架(像 EasyMockPowerMock 和 Mockito)都是非常流行的。这些框架在Groovy里也可以很容易的使用。 耶!

2. Rest-Assured

我们的后端 提供了一个REST API服务用于创建和管理用户帐号。我们的Java SDK 作为众多不同SDK中的一员,提供了一个基于特定语言的客户端模型从而简化交互。其中一些SDK还提供了一个web层,用于同后端进行交互,无需书写任何代码。

第 4 段(可获 1.21 积分)

为了确保这些web框架之间的互操作性, 它们必须表现的完全一样。因此我们需要创建一套基于HTTP的集成测试来对每一个框架进行验证。 这就是我们的兼容性测试工具包。 该项目由我们的所有的SDK工程师所维护,而他们精通不止一种编程语言。因此我们必须使用一个跟语言无关的测试工具。 多亏Rest-assured出现终于可以帮我们实现这种功能。

Rest-assured是一用于测试REST服务的简单的Java领域特定语言(DSL)。它不仅简单易用且容易上手,即使对从没有使用过Java的开发人员来说也是如此,而且还极其强大。它提供了一些高级的功能,比如细节配置、过滤器、自定义解析器对象、CSRF以及OAuth 2.0。它从头构造而成,提供了非常简单的语法:given-when-then。

第 5 段(可获 1.79 积分)

例如:让我们来看看怎么方便的验证“ 向/login发送带有正确访问凭证的post请求必须返回状态代码302这个场景

given()
    .accept(ContentType.HTML)
    .formParam("login", account.username)
    .formParam("password", account.password)
.when()
    .post(LoginRoute)
.then()
    .statusCode(302)

你还可以在我们的TCK repo看到很多不同的 Rest-assured 测试。

3. Cargo 插件

为了能让我们的Java SDK能够通过TCK的验证,我们需要启动其中一个Web示例程序以便于这些测试能够执行。逻辑上来说,我们想要让这个验证过程在每次构建的时候自动执行。Cargo插件正好就是为了这个目的而被使用起来的。

第 6 段(可获 1.08 积分)

Cargo用标准的方式封装各种类型应用容器的操作。通过Cargo,我们可以在不同的Servlet容器(像Jetty和Tomcat)里相当轻松的运行我们的样例。我们在pom文件里简单的配置Cargo Maven2插件,在集成测试阶段启动一个Tomcat7的Servlet容器,并且将刚构建的War文件部署进去。你可以在我们的Servlet Plugin Example看到一个可以工作的配置。

4. Git

关于Git还有哪些是你们不知道而值得讨论的吗?想要深入研究Git的好处,你可以简单的阅读一下它的关于页面

第 7 段(可获 1.33 积分)

我们的Java SDK 团队遍布全球并且几乎从来都没有坐在一起。Git 为我们所写的每一段代码保驾护航。这里我们总结了一些为我们节省了不少时间以及解决了不少麻烦的酷炫的命令:

  • git mv --force foo.java Foo.java :在大小写敏感的文件系统里,修改文件名的大小写真的是件很头疼的事情。这个命令可以使git明白foo.java文件被重命名为了Foo.java。
  • git diff-tree --no-commit-id --name-only -r <commit_ID>:查看在<commit_ID>这个提交里变更的所有文件。
  • git diff --name-only SHA1 SHA2:列出在SHA1和SHA2两次提交之间所有变更的文件。
  • 在一个文件的所有历史记录中查找一个字符串:
第 8 段(可获 1.23 积分)

创建一个名叫search.sh的文件,并把以下代码粘贴进去:

git rev-list --all $2 | (
    while read revision; do
        git grep -F $1 $revision $2
    done
)

然后执行这个命令即可:sh ./search.sh string_to_search file_where_to_search

5. GitHub

GitHub 不仅为我们的Git项目提供了免费的托管服务,而且将我们的源代码开放给全世界也有无价的好处。 这样可以鼓励人们尝试它,跟我们交流且参与其中,最终可以提高每个项目的质量并且使我们可以增长技术知识。

第 9 段(可获 0.89 积分)

GitHub 也允许我们跟踪我们的问题。 客户可以在上面提交功能请求以及报告Bug。他们也可以得到我们当前的进度的通知。

6. Maven

Maven 已经足够有名气了,因此我不会用以一大段文字来解释我们为什么会使用Maven来管理我们的的构建过程,这样会显得很令人讨厌的。然而,我可以分享一些有用的技巧来充分的利用Maven:

巩固依赖: 在一个多模块的项目里,你应该在pom.xml文件的<dependencyManagement> 标签内部来定义每一个单独的依赖。一旦你这样做了,那么所有的子模块都可以直接使用这些依赖,而无需指定它们的版本号。这种管理依赖(比如更新版本号)的方式可以在一个集中的地方进行,然后所有的子模块就会自动的应用这些变更。例如,根项目的 pom.xml如下:

第 10 段(可获 1.75 积分)
<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>${jjwt.version}</version>
     </dependency>
     ...
  <dependencies>
<dependencyManagement>

子模块的 pom.xml:

<dependencies>
  <dependency>
      <groupId>io.jsonwebtoken</groupId>
      <artifactId>jjwt</artifactId>  <!-- note that no version has been specified -->
  </dependency>
  ...
<dependencies>

避免子模块的部署:在发布时,我们会想要所有的子模块都一起发布,但是我们如何避免某一个子模块(比如一个示例)也被发布呢?很简单,只需要将如下内容添加到你不想发布的模块的pom文件中即可:

第 11 段(可获 0.58 积分)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-deploy-plugin</artifactId>
    <version>2.7</version>
    <configuration>
        <skip>true</skip>  <!-- this this the important line -->
    </configuration>
</plugin> 

跳过集成测试: 我们会有大量的会耗费相当长时间的集成测试。这些测试会确保与后端的交互都是正常的。在常规的本地部署中,我们在新的功能或修复完成前会多次修改代码。我们没有必要让这些针对后端验证的本地构建每次都运行,这样会明显拖慢我们的部署过程。因此,我们将Java SDK设置为只有在我们的CI (持续集成)服务器上运行时才自动运行集成测试。可以通过以下方式做到:

第 12 段(可获 1.21 积分)

在你的根pom.xml文件里:

<properties>
    <skipITs>true</skipITs>
</properties>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <skipITs>${skipITs}</skipITs>
                <includes>
                    <include>**/*IT.*</include>
                </includes>
            </configuration>
            <executions>
               <execution>
                   <goals>
                       <goal>integration-test</goal>
                       <goal>verify</goal>
                   </goals>
               </execution>
            </executions>
        </plugin>
  </plugins>
<build>
第 13 段(可获 0.05 积分)

正如你所想象的那样,所有集成测试的文件名都必须以IT两个字母结尾以便于配置能够生效。例如,ApplicationIT.groovy 或者I18nIT.groovy。

然后,当我们想要这些集成测试运行的时候,我们像这样来执行构建:mvn clean install -DskipITs=false.

7. JWT Inspector(检查器)

在我们的Java SDK里,我们重度依赖使用JWTs来确保安全且无故障的传输数据。 当测试和故障排查时,我们需要分析从浏览器接收的JWT的内容。这些token(令牌)可以是在URL中,cookie中,或者是本地存储中。JWT检查器 使我们构建的一个浏览器扩展用于帮助我们直接从控制台或者内置的UI中解码并检查JSON Web Tokens。你无须在你的应用里追踪这些token。你只需要点击下该扩展按钮,那么JWT Inspector就会自动的展示出所有你所需的信息,然后你就可以复制你所需要的任何token扩展标记。

第 14 段(可获 1.99 积分)

8. Postman

我们也及其频繁的使用到REST API 的请求。编写REST请求并不总是用户友好的;实际的语法依赖于我们使用的工具,比如curl或者HTTPie。这两个都很具有可读性的,但是有的时候记住确切的语法却是比较困难的。 此外,当进行故障排查时,我们需要测试一些请求和它们的结果。当他们失败的时候我们无法确定问题是出在了请求端还是终端那里。我们最后仅仅因为质疑我们所编写的请求的正确性而浪费了大量时间。

Postman使得编写REST API请求非常简单。它还提供了很多非常有价值的功能,比如保存和重用请求,生成代码(java、python、curl等等),还有将请求进行分组以便于顺序执行他们。Postman可以帮助你构建复杂的命令,这要得益于它极其友好的用户界面。你需要做的就只是填写一个表单。还能有比这更好的吗?

第 15 段(可获 1.89 积分)

总结

使用正确的工具不仅可以使你节省时间和减少工作,而且还可以提高你的产品的整体质量并使得你的日常工作更有乐趣。我们应该一直敞开怀抱去发现和学习新工具。这起初可能会需要一些努力,但是你会很快意识到花那些时间绝对是对得起你的付出的。

我非常乐意听到那些成为你的个人救星的开发者工具。请在下面的评论区分享给大家吧,或者在twitter上给我们留言@gostormpath

第 16 段(可获 1.11 积分)

文章评论