测试驱动开发实践1————项目代码生成
【内容指引】
领域驱动开发;
云端生成项目代码;
项目代码结构介绍。
一、领域驱动开发
1.”云开发“开发者社交平台概述
“云开发”开发者社交平台是一个基于互联网云端协作、进行软件项目管理、代码开发、全球招标、在线交付等为一体的开发者社交平台。
整个产品包含产品、项目、代码、测试、文档及团队六个模块,采用Spring Cloud微服务的方式开发,每个模块对应一个微服务。本系列文章以“文档”这个模块的微服务代码为例,探讨”云开发“平台微服务项目的测试驱动开发最佳实践,希望能抛砖引玉。
2.”文档“模块介绍
“文档”这个模块的使用场景如下:
1>.项目经理可以为项目创建及维护文档分类;
2>.该项目的成员可以为项目添加文档。
3.设计领域类:
领域类仅需声明私有字段,“云开发”平台的代码生成器会自动生成完整的领域类数据(私有字段、构造函数、get及set属性)。
文档分类(Category)
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.*/ public class Category {//文档分类private Long categoryId;//文档分类IDprivate Long projectId;//文档分类所属的项目private String name;//分类名称private Integer sequence;//排序private int DeletionAudited; }
文档(Document)
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.* docType:文档类型,1=文件,2=链接* url:文档访问网址,当类型是文件是该字段为Null*/ public class Document {//文档private Long documentId;//文档IDprivate Long categoryId;//文档所属分类private String name;//文档名称private Short docType;//文档类型private String url;//文档访问网址private String memo;//文档描述private String accessory;//附件private int DeletionAudited; }
4.关于审计字段
上面每个领域类中最后都定义了一个审计字段“DeletionAudited”:
private int DeletionAudited;
所谓审计字段,就是每个领域类中包含的创建时间、创建人员、修改时间等信息,审计字段的用法有五种:
无审计、基本审计、创建审计、修改审计和删除审计。下面用Team这个领域类为例,展示用不同审计字段生成的代码区别:
无审计
即,不定义审计字段。
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.*/ public class Category {//文档分类private Long categoryId;//文档分类IDprivate Long projectId;//文档分类所属的项目private String name;//分类名称private Integer sequence;//排序 }
“云开发”平台生成的成品领域类代码如下:
package top.cloudev.doc.domain;import org.hibernate.annotations.DynamicUpdate; import org.hibernate.validator.constraints.*; import javax.persistence.*; import javax.validation.constraints.*; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java.util.UUID;/*** Category(文档分类) 的领域层* Created by Mac.Manon on 2018/04/02*/@Entity @DynamicUpdate(true) @Table(name="tbl_category") public class Category implements Serializable {private static final long serialVersionUID = 1L;public interface CheckCreate{};public interface CheckModify{};/*** 文档分类ID*/@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id")private Long categoryId;/*** 文档分类所属的项目*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "project_id")private Long projectId;/*** 分类名称*/@NotBlank(groups={CheckCreate.class, CheckModify.class})@Length(min = 1, max = 50, groups={CheckCreate.class, CheckModify.class})//@Pattern(regexp = "", groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "name", length = 50)private String name = "";/*** 排序*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "sequence")private Integer sequence;/***TODO 请将数据表的名称及字段名称加入到国际化语言包中:TableName.category=\u6587\u6863\u5206\u7c7bFieldName.category.categoryId=\u6587\u6863\u5206\u7c7bIDFieldName.category.projectId=\u6587\u6863\u5206\u7c7b\u6240\u5c5e\u7684\u9879\u76eeFieldName.category.name=\u5206\u7c7b\u540d\u79f0FieldName.category.sequence=\u6392\u5e8f***Tip:*如果后续加入引用类型字段,可考虑使用@Valid注解;*如果后续加入Collection、Map和数组类型字段,可考虑使用@Size(max, min)注解;*//***空构造函数**/public Category(){super();}/***带参构造函数**/public Category(Long projectId,String name,Integer sequence){super();this.projectId = projectId;this.name = name;this.sequence = sequence;}/***Getter,Setter**/public Long getCategoryId() {return categoryId;}public void setCategoryId(Long categoryId) {this.categoryId = categoryId;}public Long getProjectId() {return projectId;}public void setProjectId(Long projectId) {this.projectId = projectId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getSequence() {return sequence;}public void setSequence(Integer sequence) {this.sequence = sequence;}@Overridepublic String toString() {return "Category [categoryId=" + categoryId + "," + "projectId=" + projectId + "," + "name=" + name + "," + "sequence=" + sequence + "]";} }
基本审计(HasCreationTime)
即,在原定义的领域类字段基础上自动加上创建时间(creationTime)这个字段。
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.*/ public class Category {//文档分类private Long categoryId;//文档分类IDprivate Long projectId;//文档分类所属的项目private String name;//分类名称private Integer sequence;//排序private int HasCreationTime; }
“云开发”平台生成的成品领域类代码如下:
package top.cloudev.doc.domain;import org.hibernate.annotations.DynamicUpdate; import org.hibernate.validator.constraints.*; import javax.persistence.*; import javax.validation.constraints.*; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java.util.UUID;/*** Category(文档分类) 的领域层* Created by Mac.Manon on 2018/04/02*/@Entity @DynamicUpdate(true) @Table(name="tbl_category") public class Category implements Serializable {private static final long serialVersionUID = 1L;public interface CheckCreate{};public interface CheckModify{};/*** 文档分类ID*/@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id")private Long categoryId;/*** 文档分类所属的项目*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "project_id")private Long projectId;/*** 分类名称*/@NotBlank(groups={CheckCreate.class, CheckModify.class})@Length(min = 1, max = 50, groups={CheckCreate.class, CheckModify.class})//@Pattern(regexp = "", groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "name", length = 50)private String name = "";/*** 排序*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "sequence")private Integer sequence;/*** 创建时间*/@Column(nullable = false, name = "creation_time", updatable=false)private Date creationTime = new Date();/***TODO 请将数据表的名称及字段名称加入到国际化语言包中:TableName.category=\u6587\u6863\u5206\u7c7bFieldName.category.categoryId=\u6587\u6863\u5206\u7c7bIDFieldName.category.projectId=\u6587\u6863\u5206\u7c7b\u6240\u5c5e\u7684\u9879\u76eeFieldName.category.name=\u5206\u7c7b\u540d\u79f0FieldName.category.sequence=\u6392\u5e8f***Tip:*如果后续加入引用类型字段,可考虑使用@Valid注解;*如果后续加入Collection、Map和数组类型字段,可考虑使用@Size(max, min)注解;*//***空构造函数**/public Category(){super();}/***带参构造函数**/public Category(Long projectId,String name,Integer sequence,Date creationTime){super();this.projectId = projectId;this.name = name;this.sequence = sequence;this.creationTime = creationTime;}/***Getter,Setter**/public Long getCategoryId() {return categoryId;}public void setCategoryId(Long categoryId) {this.categoryId = categoryId;}public Long getProjectId() {return projectId;}public void setProjectId(Long projectId) {this.projectId = projectId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getSequence() {return sequence;}public void setSequence(Integer sequence) {this.sequence = sequence;}public Date getCreationTime() {return creationTime;}public void setCreationTime(Date creationTime) {this.creationTime = creationTime;}@Overridepublic String toString() {return "Category [categoryId=" + categoryId + "," + "projectId=" + projectId + "," + "name=" + name + "," + "sequence=" + sequence + ",creationTime=" + creationTime + "]";} }
创建审计(CreationAudited)
即,在基本审计的基础上加上创建者(creatorUserId)这个字段。
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.*/ public class Category {//文档分类private Long categoryId;//文档分类IDprivate Long projectId;//文档分类所属的项目private String name;//分类名称private Integer sequence;//排序private int CreationAudited; }
“云开发”平台生成的成品领域类代码如下:
package top.cloudev.doc.domain;import org.hibernate.annotations.DynamicUpdate; import org.hibernate.validator.constraints.*; import javax.persistence.*; import javax.validation.constraints.*; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java.util.UUID;/*** Category(文档分类) 的领域层* Created by Mac.Manon on 2018/04/02*/@Entity @DynamicUpdate(true) @Table(name="tbl_category") public class Category implements Serializable {private static final long serialVersionUID = 1L;public interface CheckCreate{};public interface CheckModify{};/*** 文档分类ID*/@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id")private Long categoryId;/*** 文档分类所属的项目*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "project_id")private Long projectId;/*** 分类名称*/@NotBlank(groups={CheckCreate.class, CheckModify.class})@Length(min = 1, max = 50, groups={CheckCreate.class, CheckModify.class})//@Pattern(regexp = "", groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "name", length = 50)private String name = "";/*** 排序*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "sequence")private Integer sequence;/*** 创建时间*/@Column(nullable = false, name = "creation_time", updatable=false)private Date creationTime = new Date();/*** 创建者*/@Column(nullable = false, name = "creator_user_id", updatable=false)private long creatorUserId;/***TODO 请将数据表的名称及字段名称加入到国际化语言包中:TableName.category=\u6587\u6863\u5206\u7c7bFieldName.category.categoryId=\u6587\u6863\u5206\u7c7bIDFieldName.category.projectId=\u6587\u6863\u5206\u7c7b\u6240\u5c5e\u7684\u9879\u76eeFieldName.category.name=\u5206\u7c7b\u540d\u79f0FieldName.category.sequence=\u6392\u5e8f***Tip:*如果后续加入引用类型字段,可考虑使用@Valid注解;*如果后续加入Collection、Map和数组类型字段,可考虑使用@Size(max, min)注解;*//***空构造函数**/public Category(){super();}/***带参构造函数**/public Category(Long projectId,String name,Integer sequence,Date creationTime,long creatorUserId){super();this.projectId = projectId;this.name = name;this.sequence = sequence;this.creationTime = creationTime;this.creatorUserId = creatorUserId;}/***Getter,Setter**/public Long getCategoryId() {return categoryId;}public void setCategoryId(Long categoryId) {this.categoryId = categoryId;}public Long getProjectId() {return projectId;}public void setProjectId(Long projectId) {this.projectId = projectId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getSequence() {return sequence;}public void setSequence(Integer sequence) {this.sequence = sequence;}public Date getCreationTime() {return creationTime;}public void setCreationTime(Date creationTime) {this.creationTime = creationTime;}public long getCreatorUserId() {return creatorUserId;}public void setCreatorUserId(long creatorUserId) {this.creatorUserId = creatorUserId;}@Overridepublic String toString() {return "Category [categoryId=" + categoryId + "," + "projectId=" + projectId + "," + "name=" + name + "," + "sequence=" + sequence + ",creationTime=" + creationTime + ",creatorUserId=" + creatorUserId + "]";} }
修改审计(ModificationAudited)
即,在创建审计的基础上加上最近修改时间(lastModificationTime)和最近修改者(lastModifierUserId)这两个字段。
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.*/ public class Category {//文档分类private Long categoryId;//文档分类IDprivate Long projectId;//文档分类所属的项目private String name;//分类名称private Integer sequence;//排序private int ModificationAudited; }
“云开发”平台生成的成品领域类代码如下:
package top.cloudev.doc.domain;import org.hibernate.annotations.DynamicUpdate; import org.hibernate.validator.constraints.*; import javax.persistence.*; import javax.validation.constraints.*; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java.util.UUID;/*** Category(文档分类) 的领域层* Created by Mac.Manon on 2018/04/02*/@Entity @DynamicUpdate(true) @Table(name="tbl_category") public class Category implements Serializable {private static final long serialVersionUID = 1L;public interface CheckCreate{};public interface CheckModify{};/*** 文档分类ID*/@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id")private Long categoryId;/*** 文档分类所属的项目*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "project_id")private Long projectId;/*** 分类名称*/@NotBlank(groups={CheckCreate.class, CheckModify.class})@Length(min = 1, max = 50, groups={CheckCreate.class, CheckModify.class})//@Pattern(regexp = "", groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "name", length = 50)private String name = "";/*** 排序*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "sequence")private Integer sequence;/*** 创建时间*/@Column(nullable = false, name = "creation_time", updatable=false)private Date creationTime = new Date();/*** 创建者*/@Column(nullable = false, name = "creator_user_id", updatable=false)private long creatorUserId;/*** 最近修改时间*/@Column(name = "last_modification_time")private Date lastModificationTime;/*** 最近修改者*/@Column(name = "last_modifier_user_id")private long lastModifierUserId;/***TODO 请将数据表的名称及字段名称加入到国际化语言包中:TableName.category=\u6587\u6863\u5206\u7c7bFieldName.category.categoryId=\u6587\u6863\u5206\u7c7bIDFieldName.category.projectId=\u6587\u6863\u5206\u7c7b\u6240\u5c5e\u7684\u9879\u76eeFieldName.category.name=\u5206\u7c7b\u540d\u79f0FieldName.category.sequence=\u6392\u5e8f***Tip:*如果后续加入引用类型字段,可考虑使用@Valid注解;*如果后续加入Collection、Map和数组类型字段,可考虑使用@Size(max, min)注解;*//***空构造函数**/public Category(){super();}/***带参构造函数**/public Category(Long projectId,String name,Integer sequence,Date creationTime,long creatorUserId,Date lastModificationTime,long lastModifierUserId){super();this.projectId = projectId;this.name = name;this.sequence = sequence;this.creationTime = creationTime;this.creatorUserId = creatorUserId;this.lastModificationTime = lastModificationTime;this.lastModifierUserId = lastModifierUserId;}/***Getter,Setter**/public Long getCategoryId() {return categoryId;}public void setCategoryId(Long categoryId) {this.categoryId = categoryId;}public Long getProjectId() {return projectId;}public void setProjectId(Long projectId) {this.projectId = projectId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getSequence() {return sequence;}public void setSequence(Integer sequence) {this.sequence = sequence;}public Date getCreationTime() {return creationTime;}public void setCreationTime(Date creationTime) {this.creationTime = creationTime;}public long getCreatorUserId() {return creatorUserId;}public void setCreatorUserId(long creatorUserId) {this.creatorUserId = creatorUserId;}public Date getLastModificationTime() {return lastModificationTime;}public void setLastModificationTime(Date lastModificationTime) {this.lastModificationTime = lastModificationTime;}public long getLastModifierUserId() {return lastModifierUserId;}public void setLastModifierUserId(long lastModifierUserId) {this.lastModifierUserId = lastModifierUserId;}@Overridepublic String toString() {return "Category [categoryId=" + categoryId + "," + "projectId=" + projectId + "," + "name=" + name + "," + "sequence=" + sequence + ",creationTime=" + creationTime + ",creatorUserId=" + creatorUserId + ",lastModificationTime=" + lastModificationTime + ",lastModifierUserId=" + lastModifierUserId + "]";} }
删除审计(ModificationAudited)
即,在修改审计的基础上加上已删除(isDeleted)、删除时间(deletionTime)和删除者(deleterUserId)这三个字段。注意,应用了删除审计的代码才用非物理删除,否则采用物理删除!
package top.cloudev.entity;/*** Created by mac.manon on 2018/4/2.*/ public class Category {//文档分类private Long categoryId;//文档分类IDprivate Long projectId;//文档分类所属的项目private String name;//分类名称private Integer sequence;//排序private int DeletionAudited; }
“云开发”平台生成的成品领域类代码如下:
package top.cloudev.doc.domain;import org.hibernate.annotations.DynamicUpdate; import org.hibernate.validator.constraints.*; import javax.persistence.*; import javax.validation.constraints.*; import javax.validation.constraints.Pattern; import java.io.Serializable; import java.math.BigDecimal; import java.util.Date; import java.util.UUID;/*** Category(文档分类) 的领域层* Created by Mac.Manon on 2018/04/02*/@Entity @DynamicUpdate(true) @Table(name="tbl_category") public class Category implements Serializable {private static final long serialVersionUID = 1L;public interface CheckCreate{};public interface CheckModify{};/*** 文档分类ID*/@Id@GeneratedValue(strategy = GenerationType.AUTO)@Column(name = "id")private Long categoryId;/*** 文档分类所属的项目*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "project_id")private Long projectId;/*** 分类名称*/@NotBlank(groups={CheckCreate.class, CheckModify.class})@Length(min = 1, max = 50, groups={CheckCreate.class, CheckModify.class})//@Pattern(regexp = "", groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "name", length = 50)private String name = "";/*** 排序*///@Range(min=value,max=value, groups={CheckCreate.class, CheckModify.class})@Column(nullable = false, name = "sequence")private Integer sequence;/*** 创建时间*/@Column(nullable = false, name = "creation_time", updatable=false)private Date creationTime = new Date();/*** 创建者*/@Column(nullable = false, name = "creator_user_id", updatable=false)private long creatorUserId;/*** 最近修改时间*/@Column(name = "last_modification_time")private Date lastModificationTime;/*** 最近修改者*/@Column(name = "last_modifier_user_id")private long lastModifierUserId;/*** 已删除*/@Column(nullable = false, name = "is_deleted")private Boolean isDeleted = false;/*** 删除时间*/@Column(name = "deletion_time")private Date deletionTime;/*** 删除者*/@Column(name = "deleter_user_id")private long deleterUserId;/***TODO 请将数据表的名称及字段名称加入到国际化语言包中:TableName.category=\u6587\u6863\u5206\u7c7bFieldName.category.categoryId=\u6587\u6863\u5206\u7c7bIDFieldName.category.projectId=\u6587\u6863\u5206\u7c7b\u6240\u5c5e\u7684\u9879\u76eeFieldName.category.name=\u5206\u7c7b\u540d\u79f0FieldName.category.sequence=\u6392\u5e8f***Tip:*如果后续加入引用类型字段,可考虑使用@Valid注解;*如果后续加入Collection、Map和数组类型字段,可考虑使用@Size(max, min)注解;*//***空构造函数**/public Category(){super();}/***带参构造函数**/public Category(Long projectId,String name,Integer sequence,Date creationTime,long creatorUserId,Date lastModificationTime,long lastModifierUserId,Boolean isDeleted,Date deletionTime,long deleterUserId){super();this.projectId = projectId;this.name = name;this.sequence = sequence;this.creationTime = creationTime;this.creatorUserId = creatorUserId;this.lastModificationTime = lastModificationTime;this.lastModifierUserId = lastModifierUserId;this.isDeleted = isDeleted;this.deleterUserId = deleterUserId;this.deletionTime = deletionTime;}/***Getter,Setter**/public Long getCategoryId() {return categoryId;}public void setCategoryId(Long categoryId) {this.categoryId = categoryId;}public Long getProjectId() {return projectId;}public void setProjectId(Long projectId) {this.projectId = projectId;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getSequence() {return sequence;}public void setSequence(Integer sequence) {this.sequence = sequence;}public Date getCreationTime() {return creationTime;}public void setCreationTime(Date creationTime) {this.creationTime = creationTime;}public long getCreatorUserId() {return creatorUserId;}public void setCreatorUserId(long creatorUserId) {this.creatorUserId = creatorUserId;}public Date getLastModificationTime() {return lastModificationTime;}public void setLastModificationTime(Date lastModificationTime) {this.lastModificationTime = lastModificationTime;}public long getLastModifierUserId() {return lastModifierUserId;}public void setLastModifierUserId(long lastModifierUserId) {this.lastModifierUserId = lastModifierUserId;}public Boolean getIsDeleted() {return isDeleted;}public void setIsDeleted(Boolean isDeleted) {this.isDeleted = isDeleted;}public Date getDeletionTime() {return deletionTime;}public void setDeletionTime(Date deletionTime) {this.deletionTime = deletionTime;}public long getDeleterUserId() {return deleterUserId;}public void setDeleterUserId(long deleterUserId) {this.deleterUserId = deleterUserId;}@Overridepublic String toString() {return "Category [categoryId=" + categoryId + "," + "projectId=" + projectId + "," + "name=" + name + "," + "sequence=" + sequence + ",creationTime=" + creationTime + ",creatorUserId=" + creatorUserId + ",lastModificationTime=" + lastModificationTime + ",lastModifierUserId=" + lastModifierUserId + ",isDeleted=" + isDeleted + ",deletionTime=" + deletionTime + ",deleterUserId=" + deleterUserId + "]";} }
二、云端生成项目代码:
将上述文档分类(Category)和文档(Document)这两个领域类打包成zip压缩包,上传到“云开发”平台,点击“生成微服务项目代码”,“云开发”平台会根据上传的领域类批量生成微服务初始化代码。代码生成完毕后,点击“打包下载”即可。
在正式进行Spring Cloud微服务项目测试驱动开发之前,请在Github上获取本教程所需的初始化项目代码:
Github代码获取:https://github.com/MacManon/top_cloudev_doc
三、项目代码结构介绍

转载于:https://www.cnblogs.com/cloud-dev/p/ce-shi-qu-dong-kai-fa-shi-jian1xiang-mu-dai-ma-she.html
测试驱动开发实践1————项目代码生成相关推荐
- python测试驱动开发 中文版_GitHub - starryrbs/python_tdd: 使用Python测试驱动开发完成Django项目...
我知道你会问:"你是谁,为什么要写这本书,我为什么要读这本书?" 我至今仍然处在编程事业的初期.人们说,不管从事什么工作,都要历经从新手到熟手的 过程,最终有可能成为大师.我要说的 ...
- Android测试驱动开发实践
在Android应用开发中,相信很少有人在坚持先由设计人员做完整的概要设计 .详细设计,然后交给程序员进行编码实现了.通常是在有一个大体框架的情况下,就开始进行具体编码开发了.在这种情形下,开发速度可 ...
- TDD测试驱动开发入门实践
最近和团队同学们分享了测试驱动开发实践,把分享的内容同步在博客上,主要分为三个方面,简单介绍软件测试的发展历程,为什么需要使用TDD,TDD的在编码中的实践. 一,软件测试的发展历程 调试为主: 怎 ...
- 对测试驱动开发的一些理解
对测试驱动开发的一些理解 测试驱动开发解决什么问题? 系统测试和集成测试不容易覆盖一些代码细节,难以做到很高的代码覆盖率:测试驱动开发编写的测试一般是单元测试,而且由开发者编写,针对单个模块容易做到各 ...
- 「敏捷架构」核心实践:测试驱动开发(TDD)简介
测试驱动开发(TDD) 是一种渐进的开发方法,它结合了测试优先的开发,即在编写足够的产品代码以完成测试和重构之前编写测试.TDD的主要目标是什么?一个观点是TDD的目标是规范而不是验证(Martin, ...
- 【架构 Flutter实践 Clean架构 TDD测试驱动开发---1.0】
----------- 2022-11-12 补充 ----------- 最近在开发中尝试用了clean架构,感觉就是 麻烦...太多模板代码,很容易过度开发. 我认为了解这些理念是很重要的,但应该 ...
- 测试驱动开发(TDD)的实践
测试驱动开发(TDD)的实践 本文作者: Mr.J 本文链接: https://jiangtj.com/articles/almond/test-driven%20development/ 测试驱动开 ...
- 测试驱动开发 测试前移_测试驱动的开发可能看起来是工作的两倍-但无论如何您都应该这样做...
测试驱动开发 测试前移 by Navdeep Singh 通过Navdeep Singh 测试驱动的开发可能看起来是工作的两倍-但无论如何您都应该这样做 (Test-driven developmen ...
- 掌握测试驱动开发的3个关键因素(译)
从戴维恩斯坦教数千软件开发者们如何更有效地以测试驱动开发的10年来,他学会了掌握测试驱动开发的3个关键组成部分:理解它真正是什么,使代码稳定可测,并且获得实际动手经验.让我们看这些因素,找到它在你的项 ...
最新文章
- 吴恩达:AI未来将呈现四大发展趋势
- 了解这些设计原则,助你打造最佳用户体验
- zk 08之:Curator之一:zk客户端Curator
- VMware配置linux网络步骤
- org.apache.http.NoHttpResponseException
- Python的if判断与while循环
- 最简单方法远程调试Python多进程子程序
- python多进程共享变量,附共享图像内存实例
- C++ 任意进制相互转换
- Cordova原理一
- 十五、Oracle学习笔记:序列(用于表字段值自增)
- 算法:回溯五 数组全排列permutations
- matlab实验 信号处理,数字信号处理MATLAB实现与实验
- 论文中三线式表格的快速插入(word)
- 计算机机试题Excel,2009年职称计算机考试_Excel机试题-1
- Unity学习笔记1 锁定摄像机镜头跟随角色移动
- shiro学习详解(开篇)
- 如何预防 XSS 攻击
- 【NanoPi T2】 7.uboot gmac网卡驱动(3) - 驱动源码解析
- 711问题-优化蛮力求解