@testing-library/react có ba nhóm query, khác nhau ở chỗ element không tồn tại thì chuyện gì xảy ra:
getBy— throw error ngay. Dùng khi element bắt buộc phải có; fail nhanh và thông báo rõ nhất.queryBy— trả vềnull. Dùng để khẳng định element KHÔNG có:expect(queryByRole('alert')).not.toBeInTheDocument().findBy— trả về Promise và chờ element xuất hiện (mặc định 1000ms, đổi được). Dùng sau các thao tác async như gọi API.
Ba nhóm này đều có bản số nhiều: getAllBy / queryAllBy / findAllBy.
Thứ tự ưu tiên Testing Library khuyến nghị: getByRole > getByLabelText > getByPlaceholderText > getByText > getByDisplayValue > getByAltText > getByTitle > getByTestId.
getByRole('button', { name: 'Submit' }) là lựa chọn tốt nhất vì nó test đúng thứ user nhìn thấy và tiện thể kiểm luôn accessibility. Đừng dùng getByTestId cho mọi thứ — data-testid là phương án cuối, và nó buộc test dính vào chi tiết cài đặt.
Với thứ xuất hiện muộn thì dùng waitFor, nó retry assertion tới khi pass hoặc hết giờ:
js
await waitFor(() => expect(screen.getByText('Loaded')).toBeInTheDocument())