🌸

Turborepoのルートでapps配下の各リポジトリのJestを実行する

2024/12/29に公開

はじめに

Turborepoを使用して、ExpoとExpressの簡単なサンプルテストの実装を行ったので、その実装方法について書きます。

ディレクトリ構成はこちら

root/
├── apps/
│   ├── api/ //Express格納
│   ├── mobile/ //Expo格納
├── turbo.json

ExpoにJestとRNTL(React Native Testing Library)をインストール

ExpoにJestとRNTLをインストールします。

$ npx expo install -- --save-dev jest-expo jest @types/jest
$ npx expo install -- --save-dev @testing-library/react-native
$ npm install --save-dev jest @testing-library/react @testing-library/react-native @testing-library/jest-native jest-expo

index.tsxの実装はこちらです。

apps/mobile/src/app/home/index.tsx
import { Link } from 'expo-router'
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'

export default function Tab() {
  return (
    <View style={styles.container}>
      <Text>【Stack】 ホーム</Text>
      <Link href="/">👉 【Stack】 新規登録</Link>
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
})

上記の実装に合わせて、テストコードを書きました。

apps/mobile/src/app/home/index.test.tsx
import { render } from '@testing-library/react-native';
import React from 'react';

import Page from '../index';

describe('<Tab />', () => {
  test('Text renders correctly on Page', () => {
    const { getByText } = render(<Page />);

    getByText('【Stack】 ホーム');
  });
});
テストがこけた

こけた理由は、react-nativeのインポートをreactにしていたことでした。

import { render } from '@testing-library/react';//ここをreactにしていたのが原因
import React from 'react';

import Page from '../index';

describe('<Tab />', () => {
  test('Text renders correctly on Page', () => {
    const { getByText } = render(<Page />);

    getByText('【Stack】 ホーム');
  });
});

import { render } from '@testing-library/react';をimport { render } from '@testing-library/react-native';にしたら解消しました。

mobileで下記のコマンドを実行します。

$ npm run dev

テストが通っていたら成功です🎉

Expressにexampleのテストを入れる

server.tsの実装はこちらです。

apps/api/src/server.ts
import gracefulShutdown from 'http-graceful-shutdown'
import createServer from './app'
import { env } from './utils/env/env'
import log from './utils/logger/logger'

const start = () => {
  const app = createServer

  const server = app.listen(env.PORT, () => {
    log.info(`🚀 App listening on port ${env.PORT}`)
    log.info('Press Ctrl+C to quit.')
  })

  // プロセスの途中で強制終了するのを防ぐ
  // もし、本番環境でトランザクション中に強制終了してしまうとその時点で破綻
  gracefulShutdown(server, {
    finally() {
      log.info('Server graceful shut down completed.')
    },
  })

  // disable timeout
  server.timeout = 0
  // TODO: AWSのLBのKeepAliveに合わせて設定
  // server.keepAliveTimeout = 620 * 1000;
}

start()

apps/api/src/server.test.tsにサンプルのテストをおきます。

apps/api/src/server.test.ts
describe('Example Test', () => {
  it('should pass', () => {
    expect(true).toBe(true);
  });
});

apiで下記のコマンドを実行します。

$ npm run dev

テストが通っていたら成功です🎉

Turborepoのルートから個別のリポジトリのテストを通す

下記のドキュメントを参考に、turbo.jsonに記述していきます。
https://turbo.hector.im/repo/docs/handbook/testing

turbo.jsonに下記コードを記述します。

turbo.json
{
  "$schema": "https://turbo.build/schema.json",
  "ui": "tui",
  "tasks": {
    ・・・
    "test": { //ここを追加!
      "outputs": ["coverage/**", "reports/**"],
      "cache": false
    }
  }
}

package.jsonに下記コードを記述します。

package.json
{
  "name": "mii",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ],
  "scripts": {
    "build": "turbo build",
    "dev": "turbo dev prisma:studio",
    ・・・
    "manypkg:fix": "manypkg fix",//ここを追加!
    "test": "turbo run test"//ここを追加!
  },
  ・・・
}

これで、Turborepoのルートでnpm run testすると、apps配下のExpoリポジトリのテストも通ります🎉

カバレッジ

カバレッジレポートは、コードがどの程度テストされているかを把握するのに役立つので、入れてもいいかもしれません。
package.jsonに下記コードを実装します。

apps/mobile/package.json
"jest": {
    "preset": "jest-expo"
    "preset": "jest-expo",
    "transformIgnorePatterns": [
      "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@sentry/react-native|native-base|react-native-svg)"
    ]

https://docs.expo.dev/develop/unit-testing/#code-coverage-reports

下記のコマンドを打つと、Web上でカバレッジが見れるので、ぜひやってみてください。

$ open ./apps/mobile/coverage/lcov-report/index.html

Discussion