tdd java_Java TDD简介–第2部分

tdd java

再次问好! 在上一篇博客文章中,我在没有紧密引用Java的情况下总体上解释了 ,但是在这一部分中,我们开始进行TDD实践。 我们的目标是遍历TDD的所有阶段:从需求分析到测试代码的重构。 我们将在具有Java,JUnit和“ fake”需求的示例中完成所有这些工作。

需求分析

假设我们需要在一个虚构的应用程序中创建一个新功能。 以下用户故事描述了此功能:

作为用户,我希望能够创建一个帐户。 该帐户应包含ID,状态(有效/无效),区域和余额。 余额属性不能为负。 默认情况下,帐户应处于活动状态,在#1区域中且余额为0.00。

这就是抽象开发团队中常见的用户故事。 在实践中,需要在前端开发人员和后端开发人员之间分离功能。 我们还假设团队中已经存在一些代码约定等。

因此,在将功能分配给我作为后端开发人员之后,我需要澄清所有我不清楚的问题。 例如, 区域属性的目的是什么?

答:在应用程序的交易中使用区域。 根据区域的不同,我们会从帐户收取不同的费用。 目前,我们仅计划3个区域。

好。 现在一切都清楚了,我们可以开始TDD了。

Java TDD:首次测试

这是我们在项目中需要具备的依赖项:

<dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.javamoney</groupId>
            <artifactId>moneta</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-library</artifactId>
            <version>1.3</version>
        </dependency>
    </dependencies>

我使用Maven,但是您也可以使用Gradle或任何其他依赖项管理工具。 最后,我需要执行第一个实际的开发步骤:创建空的Account类和相应的测试类。 那是Intellij IDEA中的项目结构:

TDD项目结构

注意Account类的位置和AccountTest类。 它们具有相同的软件包名称,但目录不同。 那是某种约定。

回顾用户故事,我想创建以下单元测试:

  1. 默认帐户创建
  2. 自定义帐户创建
  3. 检查负余额情况

以下是测试方法:

package com.model;

import org.javamoney.moneta.Money;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class AccountTest {

    @Test
    public void defaultAccountCreationTest() {
        Account account = new Account();
        assertThat(account.getId().length(), equalTo(6));
        assertThat(account.getStatus(), equalTo(true));
        assertThat(account.getZone(), equalTo(Account.Zone.ZONE_1));
        assertThat(account.getBalance(), equalTo(Money.of(0.00, "USD")));
    }

    @Test
    public void customAccountCreationTest() {
        Account account = new Account(false, Account.Zone.ZONE_3, 125.95);
        assertThat(account.getId().length(), equalTo(6));
        assertThat(account.getStatus(), equalTo(false));
        assertThat(account.getZone(), equalTo(Account.Zone.ZONE_3));
        assertThat(account.getBalance(), equalTo(Money.of(125.95, "USD")));
    }

    @Test(expected = IllegalArgumentException.class)
    public void negativeBalanceTest() {
        Account account = new Account(false, Account.Zone.ZONE_3, -200);
    }

}

测试完成后,就该看看我们在Account类中得到了什么。 因为在单元测试开发中,我还在Account类中创建了所需方法,构造函数和属性的伪声明。

业务逻辑实施

单元测试完成后,我们需要在Account类中看到以下内容:

package com.model;

import org.javamoney.moneta.Money;

public class Account {

    private String id;
    private boolean status;
    private Zone zone;
    private Money balance;

    public Account() {}

    public Account(boolean status, Zone zone, double balance) {

    }

    public enum Zone {
        ZONE_1, ZONE_2, ZONE_3
    }

    public String getId() {
        return id;
    }

    public boolean getStatus() {
        return status;
    }

    public Zone getZone() {
        return zone;
    }

    public Money getBalance() {
        return balance;
    }

}

如上所示,从功能的角度来看, Account类并不理想。 构造函数没有用,所有属性均未初始化。 但是测试驱动的开发意味着在单元测试创​​建阶段会出现这种情况。

当我们为Account类运行单元测试时,将得到“红色”结果。 因此,使它们绿色的方法是从defaultAccountCreationTest()开始 。 在此测试的上下文中,我们必须更新Account类。 更改很小,但是更改之后,单元测试变为绿色。

package com.model;

import org.apache.commons.lang3.RandomStringUtils;
import org.javamoney.moneta.Money;

public class Account {

    private String id = RandomStringUtils.randomAlphanumeric(6);
    private boolean status = true;
    private Zone zone = Zone.ZONE_1;
    private Money balance = Money.of(0.00, "USD");

    public Account() {}
//next code is omitted, it was not affected by the first changes

您可以运行更新的AccountTest类。 运行的结果是:一个测试通过,两个失败。
然后,我们需要对每个单元测试重复此操作,直到它们全部变为“绿色”为止。

那是Account类的最终版本:

package com.model;

import org.apache.commons.lang3.RandomStringUtils;
import org.javamoney.moneta.Money;

public class Account {

    private String id = RandomStringUtils.randomAlphanumeric(6);
    private boolean status = true;
    private Zone zone = Zone.ZONE_1;
    private Money balance = Money.of(0.00, "USD");

    public Account() {}

    public Account(boolean status, Zone zone, double balance) {
        this.status = status;
        this.zone = zone;
        if (balance < 0)
            throw new IllegalArgumentException("The balance can not be negative");
        this.balance = Money.of(balance, "USD");
    }

    public enum Zone {
        ZONE_1, ZONE_2, ZONE_3
    }

    public String getId() {
        return id;
    }

    public boolean getStatus() {
        return status;
    }

    public Zone getZone() {
        return zone;
    }

    public Money getBalance() {
        return balance;
    }

}

这是运行测试的屏幕截图:

测试结果

经过测试重构

可能在更复杂的示例中,测试变成绿色后,我将进行一些重构。 但是在这种简单情况下,我们不需要这个。 如果您对提高代码的可读性或样式有任何建议,请随时发表评论。

摘要

在本教程中,我们研究了如何使用Java使用TDD进行开发 ,从功能分析开始,以“绿色”单元测试和重构结束。 我试图在示例中解释TDD方法,该方法虽然不太琐碎,但也不太复杂。 无论如何,我希望它对您有所帮助并提供有益的信息。

翻译自: https://www.javacodegeeks.com/2015/11/introduction-java-tdd-part-2.html

tdd java

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
测试驱动的编程是 XP 困扰程序员的一个方面。对于测试驱动的编程意味着什么以及如何去做,大多数人都做出了不正确的假设。这个月,XP 方面的讲师兼 Java 开发人员 Roy Miller 谈论了测试驱动的编程是什么,它为什么可以使程序员的生产力和质量发生巨大变化,以及编写测试的原理。请在与本文相随的 论坛中提出您就本文的想法,以飨笔者和其他读者。(您也可以单击本文顶部或底部的“讨论”来访问该论坛。) 最近 50 年来,测试一直被视为项目结束时要做的事。当然,可以在项目进行之中结合测试,测试通常并不是在 所有编码工作结束后才开始,而是一般在稍后阶段进行测试。然而,XP 的提倡者建议完全逆转这个模型。作为一名程序员,应该在编写代码 之前编写测试,然后只编写足以让测试通过的代码即可。这样做将有助于使您的系统尽可能的简单。 先编写测试 XP 涉及两种测试: 程序员测试和 客户测试。测试驱动的编程(也称为 测试为先编程)最常指第一种测试,至少我使用这个术语时是这样。测试驱动的编程是让 程序员测试(即单元测试 ― 重申一下,只是换用一个术语)决定您所编写的代码。这意味着您必须在编写代码之前进行测试。测试指出您 需要编写的代码,从而也 决定了您要编写的代码。您只需编写足够通过测试的代码即可 ― 不用多,也不用少。XP 规则很简单:如果不进行程序员测试,则您不知道要编写什么代码,所以您不会去编写任何代码。 测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量。本文从开发人员使用的角度,介绍了 TDD 优势、原理、过程、原则、测试技术、Tips 等方面。 背景 一个高效的软件开发过程对软件开发人员来说是至关重要的,决定着开发是痛苦的挣扎,还是不断进步的喜悦。国人对软件蓝领的不屑,对繁琐冗长的传统开发过程的不耐,使大多数开发人员无所适从。最近兴起的一些软件开发过程相关的技术,提供一些比较高效、实用的软件过程开发方法。其中比较基础、关键的一个技术就是测试驱动开发(Test-Driven Development)。虽然TDD光大于极限编程,但测试驱动开发完全可以单独应用。下面就从开发人员使用的角度进行介绍,使开发人员用最少的代价尽快理解、掌握、应用这种技术。下面分优势,原理,过程,原则,测试技术,Tips等方面进行讨论。 1. 优势 TDD的基本思路就是通过测试来推动整个开发的进行。而测试驱动开发技术并不只是单纯的测试工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值