からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

SharePoint Framework で gulp test を使って自動テストを実行してみる

SharePoint Framework でも自動テストを実施したいということがあります。幸い公式のドキュメントでは Jest を使ってテストを実施する方法が紹介されています。

docs.microsoft.com

この方法では package.json を書き換えて既定の gulp test ではなく Jest を直接呼び出すようになっています。それはそれでいいのですが既定の gulp test のままで実施できないのかなと思ったのでちょっと試してみました。

gulp test について

そもそも gulp test が何をするのかを理解する必要があります。SharePoint Framework のツールチェーンでは @microsoft/gulp-core-build パッケージに定義されているタスクを実行しています。

docs.microsoft.com

そこで @microsoft/gulp-core-build パッケージのソースを辿っていくと JestTask というタスクが見つかります。どうやらこれを実行しているようです。

github.com

一般的に Jest を使って TypeScript のコードをテストする場合は ts-jest を使って内部的にトランスパイルするのですが、gulp test によるテストの場合、事前の gulp タスクで tsc や webpack が実行され lib フォルダーに格納されたコードに対してテストが行われます。

サンプル コード

github.com

テストを実施する

全体的な流れはわかったので実際にテスト コードを書いていきます。まずは @types/jest をインストールします。@microsoft/gulp-core-build が使っている Jest のバージョンが 23.6.0 なのでバージョンを合わせるようにします。

npm install @types/jest@23.3.14 --save-dev

tsconfig.json で Jest が型解決できるようにします。

    "types": [
      "es6-promise",
      "webpack-env",
+     "jest"
    ],

components フォルダーに MyApplicattion.test.tsx をいうファイルを作成して適当にテスト コードを追加してみます。

// とりあえず必ず PASS するテスト
it('test1', () => {
  expect(true).toBe(true);
});

gulp test すればテストが実行されるはずですが、試してみると実行されません。JestTask のコードを見てみると、isEnabled という設定があってこれを true にする必要があるので config/jest.json を追加します。また今回は coverage は使わないので false にしておきます。

{
  "isEnabled": true,
  "coverage": false
}

これで再度 gulp test するとテストが実行されます。

[00:00:00] Starting subtask 'jest'...
 PASS  lib\webparts\my-application\components\MyApplicattion.test.js
[00:00:00] Finished subtask 'jest' after 1.5

スナップショット テストを実施する

基本的なテストができることはわかりましたが、React のスナップショット テストも実施してみたいです。まずは React をテストできるようにセットアップします。

jestjs.io

必要なパッケージをインストールします。

npm install babel-jest@22.4.4 react-test-renderer@16.8.6 @types/react-test-renderer@16.8.3 babel-preset-env babel-preset-react --save-dev

.babelrc を追加します。

{
  "presets": [
    "babel-preset-env",
    "babel-preset-react"
  ]
}

テスト コードを追加します。

import * as React from 'react';
import { create } from 'react-test-renderer';
import MyApplication from './MyApplication';
import { IMyApplicationProps } from './IMyApplicationProps';

// スナップショットを作成するテスト
it('test2', () => {
  const props = {} as IMyApplicationProps;
  const tree = create(<MyApplication {...props} />).toJSON();
  expect(tree).toMatchSnapshot();
});

これでテストを実行するとエラーが発生してしまいます。

[00:00:00] Starting subtask 'jest'...
 FAIL  lib\webparts\my-application\components\MyApplicattion.test.js
  ● Test suite failed to run

    SyntaxError: Unexpected token .

       5 |     container: 'container_835912dc',
       6 |     row: 'row_835912dc',
    >  7 |     column: 'column_835912dc',
       8 |     'ms-Grid': 'ms-Grid_835912dc',
       9 |     title: 'title_835912dc',
      10 |     subTitle: 'subTitle_835912dc',

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-cli/node_modules/jest-runtime/build/script_transformer.js:316:17)
      at Object.<anonymous> (lib/webparts/my-application/components/MyApplication.module.scss.js:7:1)
      at Object.<anonymous> (lib/webparts/my-application/components/MyApplication.js:11:28)
      at Object.<anonymous> (lib/webparts/my-application/components/MyApplicattion.test.js:9:22)

[00:00:00] Error - 'jest' sub task errored after 1.86 s
 Jest tests failed
[00:00:00] 'test' errored after 8.45 s
[00:00:00]
[00:00:00] ==================[ Finished ]==================
Error - 'jest' sub task errored after 1.86 s
 Jest tests failed

これは CSS ファイルを require しようとして失敗しているのが原因なので、モックを追加します。

qiita.com

config/jest/jest.config.json を追加します。

{
  "moduleNameMapper": {
    "\\.css$": "<rootDir>/__mocks__/cssmock.js"
  }
}

__mocks__/cssmock.js を追加します。

module.exports = '';

これでテストが成功します。

[00:00:00] Starting subtask 'jest'...
 PASS  lib\webparts\my-application\components\MyApplicattion.test.js
[00:00:00] Finished subtask 'jest' after 1.53 s
[00:00:00] Finished 'test' after 7.64 s

まとめ

やればできる。けど普通に Jest 使ったほうがいいと思います。

SPClientCore 3.11.1 を公開しました

SPClientCore 3.11.1 を公開しました。

SPClientCore は PowerShell Core 向けの SharePoint Online 管理モジュールです。

www.powershellgallery.com

ファイルおよびフォルダーのコピーおよび移動に関するコマンドレットを追加または更新しました。
また安定性向上のためにリトライをするようにしました。

提供されているコマンドレットの数は 268 になりました。

Teamtile 1.0.0 を公開しました

Teamtile という名前の Microsoft Teams アプリを公開しました。

github.com

このアプリは自分が参加しているチームの一覧をタイル状に表示します。標準のツリー表示に比べて目的のチームにアクセスしやすくなっているのが特徴です。どういうものかはスクリーンショットを見ていただくのがわかりやすいです。

https://raw.githubusercontent.com/karamem0/teamtile/master/img/screenshot.png

スクリーンショットはありませんがモバイル アプリにも対応しています。

本来はマニフェストだけ公開して提供できればよかったのですが、Azure AD のマルチテナント アプリケーションでは MPN ID が必須になったことから、個人で提供するアプリについてはマルチテナント アプリケーションにすることが難しくなりました。そのため、アプリをホストする環境についても用意していただく必要があります。インストール手順は GitHub の README.md を参照してください。

Power Apps オンライン勉強会に登壇しました

ぼーっとしてたら月が替わってしまったのですが、2021/02/19 に Power Apps オンライン勉強会に登壇しました。

powerapps.connpass.com

スライドは Speaker Deck にアップロードしています。

Power Apps 勉強会にもかかわらず半分以上スクラムの話をしているというハードな内容で申し訳ありませんでした。ただ、スクラムではなくても、アプリの ALM を考えることは大事だと思いますので、単に作ればいいというのではなく、リリースしたあともアプリを育てていくことを考えていただければと思います。

Azure Active Directory のアプリケーションをコマンド ラインから作成する

今まで Azure Active Directory のアプリケーションはいつも Azure Portal から作っていたのですが、展開するときにコード化されていないと困るので、やる方法をまとめてみました。いくつか方法があって苦労したので雑にまとめておきます。

使ってみた

AzureAD モジュール

New-AzureADApplication を使ってアプリケーションを作成することができます。

docs.microsoft.com

使ってみたところ以下の問題点がありました。

  • PowerShell Core に対応していない
  • パラメーターが超絶的に面倒くさい

Az モジュール

New-AzADApplication を使ってアプリケーションを作成することができます。

docs.microsoft.com

使ってみたところ以下の問題点がありました。

  • 設定できるパラメーターが少ない
    • 例えば oauth2AllowImplicitFlow などが指定できないです。
  • IdentifierUris を省略できない

Azure CLI

az ad app create を使ってアプリケーションを作成することができます。

docs.microsoft.com

使ってみたところ以下の問題点がありました。

  • 戻り値が受け取りにくい
    • アプリケーションを作成したあとにアプリケーション ID を使って後続の処理をするときが困ったりする。
  • 同じ名前のアプリケーションを作ることができない
    • すでに存在する同じ名前のアプリケーションの情報が自動的に上書きされます。

Microsoft.Graph モジュール

New-MgApplication を使ってアプリケーションを作成することができます。

github.com

使ってみたところ以下の問題点がありました。

  • パラメーターの形式がマニフェストの定義と若干異なる

まとめ

とりあえず Microsoft.Graph モジュールがよさそう。