LoginSignup
1
0

More than 1 year has passed since last update.

Material-UIのレンダリングを確認するテストコードを書いてみた

Last updated at Posted at 2021-03-23

 この記事では、私がはじめてreactのテストコードを書いた時に、詰まってしまった問題と、それを解決するためにとった対策について紹介しています。
 
###詰まってしまった問題
 react-testing-libraryの.getByRole()メソッドを使ってtype="password"の要素を取得しようとしたときに、テストコードのある部分でエラーになってしまいました。

###解決するためにとった対策

単純ですが、.getByRole()以外のメソッドを使用することで、対象の要素を取得することができました。 

この記事で前提としている環境

この記事は以下の環境を前提に書かれています。

(1)material-uiをインストールしている。
(2)react-testing-library と Jest をインストールしている
   ※(2)は、npx create-react-app を実行するとデフォルトでインストールされます。
(3)TypeScriptでコードが書かれている

とりあえずテストコードを書いてみた

 ログイン画面を作ろうとして、以下のとおり、Material-UIを活用して、メールアドレスとパスワードの入力するコンポーネントを作りました。

Auth.tsx

const Auth: React.FC = () => {
  const classes = useStyles();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

return (
    <>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="email">メールアドレス</InputLabel>
        <OutlinedInput
          className={classes.textField}
          value={email}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setEmail(e.target.value);
          }}
          labelWidth={100}
        />
      </FormControl>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="password">パスワード</InputLabel>
        <OutlinedInput
          className={classes.textField}
          type="password"
          value={password}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setPassword(e.target.value);
          }}
          labelWidth={80}
        />
      </FormControl>
    </>
  );

※解説に必要な箇所に絞って、ものすごく簡略化して書いています。

このコンポーネントに対し、以下のとおりテストコードを書きました。

Auth.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import Auth from "./Auth";

describe("Rendering", () => {
  it("Should render the elements correctly", () => {
    render(<Auth />);
    expect(screen.getAllByRole("textbox")[0]).toBeTruthy();
    expect(screen.getByRole("textbox"))[1].toBeTruthy();
  });
});

 すると、以下の画像のように、type="password"のinput要素を取得しようとした際にエラーが発生してしまいました。

スクリーンショット 2021-03-24 0.46.30.png

.getByRole()では、type= "password"の要素を取得することができない

以下のサイトで.getByRoleで選択できるロールの一覧を確認してみたところ、.getByRole()では、type= "password"の要素を取得することができないことがわかりました。 
 https://github.com/A11yance/aria-query

.getByTestIdを試してみる

 React-Testing-Libraryを使って、コンポーネントの要素がきちんとレンダリングされているか
確認するためには、さまざまな方法がありますが、今回はgetByTestIdを使用する方法を試してみました。

###① レンダリングの確認対象とする要素にdata-testid=""というプロパティをつける
 ※id=""という形ではない点に注意です!

Auth.tsx

const Auth: React.FC = () => {
  const classes = useStyles();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

return (
    <>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="email">メールアドレス</InputLabel>
        <OutlinedInput
          data-testid="email"
          className={classes.textField}
          value={email}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setEmail(e.target.value);
          }}
          labelWidth={100}
        />
      </FormControl>
      <FormControl className={classes.textField} variant="outlined">
        <InputLabel htmlFor="password">パスワード</InputLabel>
        <OutlinedInput
          data-testid="password"
          className={classes.textField}
          type="password"
          value={password}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
            setPassword(e.target.value);
          }}
          labelWidth={80}
        />
      </FormControl>
    </>
  );

.getByTestId("")を要素の選択条件としてテストコードを書く

Auth.test.tsx
import React from "react";
import { render, screen } from "@testing-library/react";
import Auth from "./Auth";

describe("Rendering", () => {
  it("Should render the elements correctly", () => {
    render(<Auth />);
     expect(screen.getByTestId("email")).toBeTruthy();
     expect(screen.getByTestId("password")).toBeTruthy();
  });
});

みたいな感じで。

他にもgetByRoleや getAllByrole、getByLabelTextなど、要素を選択するさまざまな条件があるので、いろいろ試してみると勉強になります。

##その他

 Auth.tsxやFeed.tsxみたいに、tsxファイルで作ったコンポーネントのテストコードは
必ずtsxファイルで書かないと、テストを実行したときエラーになるので、注意です!
自分はこのエラーで3日間ハマってしまいました ^^;

参考

Udemyの教材 Reactソフトウェアテスト(Hooks+ReduxToolKit時代のモダンテスト手法)
https://www.udemy.com/course/reacthooksreduxtoolkit/

getByクエリの概要
https://testing-library.com/docs/queries/about

getByRole で選択できるロール一覧
 https://github.com/A11yance/aria-query

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0