上一篇创建了
Counter
组件,并让测试通过。
这次将重构这个组件,改善它的结构。
1. 解决 describe 和 it 的红色下划线 🔗
即使使用
Vitest
,编辑器(如 VS Code、WebStorm)有时也会按照
Jest
的语法检查代码。
这时可能找不到
describe 或
it 等函数,并出现红色下划线。
可以将
Jest
的类型定义包安装为开发依赖来解决。
Terminal npm i --save-dev @types/jest
安装后,红色下划线应该就会消失。
2. 查看详细日志(screen.debug) 🔗
如果想看到比终端中的
PASS
更详细的信息,可以试试
RTL
提供的调试工具。
在测试代码中插入
screen.debug(),就会将当时的 HTML 结构输出到控制台。
src/components/Counter.test.tsx // ... import 생략
describe ( 'Counter 컴포넌트 동작 테스트' , () => {
test ( '...' , async () => {
const user = userEvent. setup ();
render (< Counter />);
// [팁] 클릭하기 전 화면 상태 출력
console. log ( '--- 클릭 전 ---' );
screen. debug ();
const incrementBtn = screen. getByRole ( 'button' , { name: '+' });
await user. click (incrementBtn);
// [팁] 클릭한 후 화면 상태 출력
console. log ( '--- 클릭 후 ---' );
screen. debug ();
expect (screen. getByText ( '현재 숫자: 1' )). toBeInTheDocument ();
});
});
这样,终端就会以文本形式显示当前渲染出来的 HTML(DOM)。
不知道测试为什么失败时,这是一种直接的排查方法。
现在回到正题。
目前的
Counter
组件运行正常,但结构还有改进空间。
button 标签直接写在
Counter
内部,因此无法在其他地方复用这个按钮。
接下来将按钮拆成独立的组件(
CountButton)。
关键是,
即使改动了代码结构,验证原有功能的测试也必须继续通过
。
先创建负责显示按钮的子组件。
让它从父组件接收
onClick 函数和
label(按钮名称)。
src/components/CountButton.tsx // Props 타입을 정의하여 TypeScript의 장점을 살립니다.
interface Props {
label : string ;
onClick : () => void ;
}
export default function CountButton ({ label, onClick } : Props) {
return (
< button type = "button" onClick ={ onClick } >
{ label }
</ button >
);
}
现在删除
Counter
组件中原有的
button 标签,换成刚创建的
CountButton
。
src/components/Counter.tsx import { useState } from 'react' ;
import CountButton from './CountButton' ; // [추가]
export default function Counter () {
const [ count , setCount ] = useState ( 0 );
const handleClick = () => {
setCount ( prev => prev + 1 );
};
return (
< div >
< p >현재 숫자: { count } </ p >
{ /* [변경] 기존 button 태그 대신 컴포넌트 사용 */ }
< CountButton label = "+" onClick ={ handleClick } />
</ div >
);
}
我们刚才改动了不少代码。
拆分了文件、增加了导入,还传递了 props。
万一漏了什么怎么办?
这正是 TDD 发挥作用的时候。
我们
一行测试代码都没有修改
。
直接在终端运行原来的测试。
Terminal
查看测试结果
PASS src/components/Counter.test.tsx
原有测试
:getByRole('button', { name: '+' })
修改前
:<button>+</button>(可以找到)
修改后
:<CountButton label="+" ... /> → 最终渲染的 HTML 仍是 <button>+</button>(可以找到)
从用户和测试代码的角度来看,组件内部如何拆分并不重要。关键是
界面上有 + 按钮,点击后数字会增加
。
这就是
避免测试实现细节
的好处。
Terminal git clone https://github.com/PROMLEE/my-tdd-app.git
cd my-tdd-app
git checkout part5
今天介绍了测试环境中的一些技巧,并完成了组件重构。
故障排查
通过 @types/jest 消除红色下划线,并用 screen.debug() 直观查看 HTML 结构。
重构
将按钮拆成独立组件,提高了可复用性。
测试的保护作用
改变内部结构后,无需修改测试代码,就能立即确认功能仍然正常。
如果需求不只是数字加一,而是要根据不同条件改变界面,该怎么办?
第 6 篇将介绍
状态(State)变化测试
,学习如何测试条件渲染。