想找專案練習來更認識測試的運用,至 youtube 找尋測試相關的教學。
建立 login 檔案
login.js : 製作登入元件
login.test.js : 撰寫測試
確認 輸入框 有渲染至文件
- 使用
getByPlaceholderText
取得輸入框元素
1 2 3 4 5 6 7 8 9 10 11 12
| <form> <input type="text" placeholder="username" value='' /> <input type="password" placeholder="password" value='' /> </form>
|
1 2 3 4 5 6 7 8 9 10 11
| test("username input should be rendered", () => { render(<Login />); const usernameInputEl = screen.getByPlaceholderText(/username/i); expect(usernameInputEl).toBeInTheDocument(); });
test("password input should be rendered", () => { render(<Login />); const passwordInputEl = screen.getByPlaceholderText(/password/i); expect(passwordInputEl).toBeInTheDocument(); });
|
確認畫面上有按鈕
1 2 3 4 5
| test("button should be rendered", () => { render(<Login />); const buttonEl = screen.getByRole("button"); expect(buttonEl).toBeInTheDocument(); });
|
輸入框一開始為空
1 2 3 4 5 6 7 8 9 10 11
| test("username input should be empty", () => { render(<Login />); const usernameInputEl = screen.getByPlaceholderText(/username/i); expect(usernameInputEl.value).toBe(""); });
test("password input should be empty", () => { render(<Login />); const passwordInputEl = screen.getByPlaceholderText(/password/i); expect(passwordInputEl.value).toBe(""); });
|
輸入框為空時,按鈕應為 disabled
- 只要取得按鈕元素並使用
toBeDisabled()
1 2 3 4 5
| test("button should be disabled", () => { render(<Login />); const buttonEl = screen.getByRole("button"); expect(buttonEl).toBeDisabled(); });
|
錯誤訊息的提示
- 確保一開始進入畫面,該訊息不應該出現
- 可以看見
toBeVisible()
,反之期望無法看見,就需加入not
1 2 3 4 5
| test("error message should not be visible", () => { render(<Login />); const errorEl = screen.getByTestId("error"); expect(errorEl).not.toBeVisible(); });
|
輸入框的輸入事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| test("username input should change", () => { render(<Login />); const usernameInputEl = screen.getByPlaceholderText(/username/i); const testValue = "test";
fireEvent.change(usernameInputEl, { target: { value: testValue } }); expect(usernameInputEl.value).toBe(testValue); });
test("password input should change", () => { render(<Login />); const passwordInputEl = screen.getByPlaceholderText(/password/i); const testValue = "test";
fireEvent.change(passwordInputEl, { target: { value: testValue } }); expect(passwordInputEl.value).toBe(testValue); });
|
當輸入框有值的時候,按鈕不應該 disabled
- 期望按鈕可以點擊
- 在 jsx 檔案內要設置在輸入框沒有值的時候才是 disabled
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| test("button should not be disabled when inputs exist", () => { render(<Login />); const buttonEl = screen.getByRole("button"); const usernameInputEl = screen.getByPlaceholderText(/username/i); const passwordInputEl = screen.getByPlaceholderText(/password/i);
const testValue = "test";
fireEvent.change(usernameInputEl, { target: { value: testValue } }); fireEvent.change(passwordInputEl, { target: { value: testValue } });
expect(buttonEl).not.toBeDisabled(); });
|
css 補充
1
| style={{ visibility: error ? "visible" : "hidden" }}
|
類似: display:none和visibility:hidden
而兩者差異:
visibility:的隱藏,是物件的位置仍舊保持著不會消失,
display: none, 會將 html 該物件拔除
小結
此練習範例,很請楚地知道在建立一個功能元件之後,如何再加入每一個區塊的測試,如標題文字、輸入框、按鈕的測試等等,也可以觀察到測試根據使用情境一步步的拆解並加入測試
下一篇會有串接資料搭配測試,敬請期待
參考資料
github-login
React Testing Tutorial with React Testing Library and Jest