TDD
TDD demo
Tasking
Tasking 理论
Tasking 铁三角
有价值
有业务价值
能够实现一个功能
用户能够使用,感觉到软件的变化
足够小
- 让干活的人能够开始干活
- 而不是”动不了手”或是”瞎干活”
- 是对个人来说相对的小,也不能太小,不到代码实现层面
- 跟”价值”平衡
说人话
- 沟通
- 跟非程序员(用户)沟通
- 跟你的pair沟通
- 产品思维-call back有价值
- 用使用场景和解决的问题来思考
- 而不是for map等技术细节
- 沟通
技术细节
简化场景
手段
- 预算砍半法,五到十分钟能做完,直接google就能做
- 极端假设法,只做其中一部分,干掉大部分变化因素再加回来。例如写list的时候写死completed的那部分
- 一档起步法:
举例
- 手机能怎么简化->从智能机一直简化到拨号机
- 微信/QQ怎么简化->从现在简化到只能发文字信息的messager
- 东方红卫星到天宫空间站
降维减量
- 维度
- 手段
- 举例,添加删除,切换状态三个维度
- 数量
- 找数量
- 举例task 时的name,只有一个单词作为name,或者写死name,然后再想怎么读入name
- 维度
Happy First
- 先做happy path
- 再做sad path
高频优先
- Todo App的List功能肯定比init功能用到的频率更高
典型反模式
- 不说人话,全是技术术语,甚至伪代码片段
- 万能tasking,放之四海而皆准。例如输入->处理->输出
- 拆的太大
其他注意事项
- 不用全写完,边做边写
- 不用全写对,边做边改
- 有的时候还要再拆
- 有的时候还要合并
- 有的时候还要删除一些错误的预判
跟TDD如何结合
每个task对应TDD时的一个或多个tests
最后的提醒
- 不要被输入
- 不要为了写一个好的task列表而做task
- 重在效果,不在形式
- 做正确的是情
- 能动手能起步
- 能有助于沟通
练习
Bowling Game
规则如下
- 一场游戏有10个格子
- 每一个格子有10个瓶子,初始可以扔两次球,第10个格子初始可以投三次
- 每一格有全中,补中和失误三种情况
- 全中的情况下,同一个格子再扔两次,分数为这三次的总和
- 补中的情况下,再扔一次,分数为这三次的总和
Tasking
- 计算一个格子
- 全中
- 再扔两次
- 补中
- 再扔一次
- 失误
- 全中
- 计算多个格子
- 计算最后一个格子
最初的第一个任务为,对于一个只扔两次的格子,输出他全中的分数
Args
- 没有参数
- 参数结构正确
- 没有l标记
- 一个标记,没有值
- 获取缺省值
- 一个标记,一个值
- 传入进行处理
- 多个标记,多个值
- 传入进行处理
- 一个标记,没有值
- 有l标记
- 没有l标记
- 参数结构错误
Clean Code
关于写代码
任何傻瓜都能写出来机器可以读懂的代码,优秀的程序员要写的是人可以读懂的代码
代码主要是写给人看的,偶尔让机器执行一下
看代码的时间远多于改代码的时间10x
好的设计是显而易见没有问题,糟糕的涉及是没有显而易见的问题
我们看中的是:
- Readability!Maintainability!
- ✓Problem Solver × Trouble Maker
什么是Clean Code
好的代码的总称
学习内容
Clean Code
书
一些现在就要注意和强制做到的一些点
- 1-10-50*(极个别情况可有例外)
- 每个方法不超过一层缩进
- try-catch和 JS callback可例外
- 每个方法最多不超过10行
- 不包括花括号和名字本身
- try-catch和fetch API等场景可例外
- 不要强制把多行写成一行
- 每个类最多不超过50行
- import类的语句不算
- 每个方法不超过一层缩进
- 合理的命名常量 方法 类 枚举值 文件等等
- 方法顺序 P29-P32
- “No” Comments
- “No” Else
- Return Early Pattern
4 Rules of Simple Design

The SOLID Prinnciples
- Single Responsibility
- Open/Closed
- Liskov Substitution
- Interface Segregation
- Dependency Inversion
Design Patterns
https://refactoring.guru/design-patterns/catalog

Coach推荐先红后蓝
推荐资源
推荐以下学习视频

image-20220719171122038 📺 五分钟学设计模式
推荐以下经典书籍 📚
- Robert C. Martin《代码整洁之道》 英文名:Clean Code: A Handbook of Agile Software Craftsmanship
- Robert C. Martin《程序员的职业素养》 英文名:The Clean Coder:A Code of Conduct for Professional Programmers
- Robert C. Martin《敏捷软件开发:原则、模式与实践》 Agile Software Development: Principles, Patterns, and Practices
- 《高效程序员的 45 个习惯》
- 《实现模式》
- 设计模式相关的书
- 《设计模式》
- 《Head First 设计模式》
- 《大话设计模式》
- 《重学 Java 设计模式》
推荐阅读顺序:
- 《实现模式》《代码整洁之道》
- 《程序员的职业素养》《高效程序员的 45 个习惯》
- 《敏捷软件开发:原则、模式与实践》
- 《Head First 设计模式》《设计模式》《大话设计模式》《重学 Java 设计模式》
TDD
Refactoring
Code Smell
- Duplicate Code
- Long Method
- Large Class
- Long Parameter List
- Primitive Obsession
- Data Clumps
- Switch Statements
- Feature Envy
- Comments
Refactoring Techniques
- Extract Variable
- Inline Temp
- Extract Method
- Inline Method
- ……
这里强调一下我们 现在 就要注意和 强制做到的一些点
- 使用快捷键
- 重构是不能破坏代码的功能,要始终可以编译、运行
- 不能重构着重构着就开始写上新代码了
TDD

Three laws of TDD

理解 Test Double 里的 Stub 和 Mock
- 理解为何需要使用 Stub 和 Mock
- 能够对两者进行区分
- 可以使用 Mockito 来在测试中实现 Stub 和 Mock 这里强调一下我们 现在 就要注意和 强制做到的一些点 • Test First • Follow 3 Laws
演示笔记
Note
extend selection
ctrl+D 复制粘贴
ctrl上下快速跳转
先通过测试,这一步代码可以很丑陋,然后再去重构为clean code
有一些思路就写两行代码运行一下测试
新的需要做的事情立刻加到tasking里面
git commit —amend —no-edit将这次的commit合并到上次
让每次测试的开始时环境一致的方法
@BeforeEach
void setUp
可以把一个默认的初始值给传入到文件里或者清空文件
@Aftereach
void tearDown()在执行完每个测试之后处理一些东西
Introduce Object Parameter
验证异常也是测试
git stash https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E8%B4%AE%E8%97%8F%E4%B8%8E%E6%B8%85%E7%90%86 这是干嘛的没看懂
步子太大的时候可以再度taksing
statichttps://www.cnblogs.com/dolphin0520/p/3799052.html
final https://www.cnblogs.com/dolphin0520/p/3736238.html
- 当步子有点大时该怎么办?不要忘记做 tasking。
- 模型序列化和反序列化的逻辑要放到一起
- 要对
equals进行充分的单元测试 - 基于当前代码的 模块/类 的划分 添加/补充 相应的测试以完成新的功能需求
- 如何先重构以便让新功能添加更加简单
extract super class
Test Structure:Given-When-Then、AAA
Nested test class
将测试附到某个具体的类上https://www.petrikainulainen.net/programming/testing/junit-5-tutorial-writing-nested-tests/
//AAA
//Arrange-Act-Assert
//Given- Arrange
final var app=new App();
//when-Act
final var result=app.run();
//Then-Assert
Assertions.assertEquals(expectedResult,result);Integration Test vs Unit Test
Integration Test: 读写真实的文件或者文件,几乎是针对整个软件的功能。如果把标准输出也测试了 那就是End-to-End test/e2e test
Unit Test
,一般不做泛指What is Test
SUT: System Under Test
边界隔离

以边界去看输入输出
里面有什么

不是所有代码都写在了App class里的
App相当于乐队的指挥,让别的class去干活

- 不是所有代码都写在了App class里的
- 越靠近用户界面UI越难做测试
- 有些时候做简化和忽略处理
DOC
Depended On Component

在测试SUT的时候需要引入DOC
在这种情况下可以洗的一个fake Task Repository
技巧Dependency Injection(DI, do not confuse with dependence inversion principle)
创建一个匿名类
复写override
我没看懂
https://www.youtube.com/watch?v=IKD2-MAkXyQ&t=4s
Test Double: Mock
mockito frameworkhttps://site.mockito.org/
@BeforeEach
void setUp(){
taskReo=mock(TaskRepo.class)
}在使用了这个之后,就不会跟数据文件产生交互了
equal 方法需要比较hash code,
快捷键cmd+n/alt+fn+f12,否则的话比较的是引用而不是值
Test Double的意思就是测试替身
Stub用于间接输入
Test Double: Double
order type
在setup时给mock过来的class一个输入