Выполнение модульных тестов JavaScript для библиотеки классов Razor на Visual Studio 2022 Test Explorer


Введение

Начиная с Visual Studio 2022, модульные тесты JavaScript можно легко обнаружить и запустить в Test Explorer Visual Studio. Это гораздо удобнее для разработки библиотеки классов Razor для Blazor. Когда я разрабатывал библиотеку классов Razor, содержащую вспомогательный код JavaScript для использования из кода C#, я часто хотел выполнить модульные тесты как для кода C#, так и для кода JavaScript. Visual Studio 2022 позволила мне это сделать.

Как это сделать?

Предположим, что у вас уже есть проект модульного тестирования для библиотеки классов Razor, в частности для кода на C#. В таком случае вы можете сделать так, чтобы этот проект модульного тестирования дополнительно выполнял тесты для кода JavaScript, просто добавив несколько шагов, как показано ниже.

1) Добавьте свойство <JavaScriptTestFramework> в файл проекта модульного тестирования (.csproj), чтобы указать, какой фреймворк модульного тестирования JavaScript вы используете. А также добавьте свойство <JavaScriptTestRoot>, чтобы указать относительный путь, по которому размещаются коды модульных тестов.

Следующий пример показывает использование “mocha”, одного из известных фреймворков для тестирования JavaScript.

<!-- A .csproj file of your unit test project -->
<Project Sdk="Microsoft.NET.Sdk">
  ...
  <PropertyGroup>
    <JavaScriptTestFramework>Mocha</JavaScriptTestFramework>
    <JavaScriptTestRoot>tests</JavaScriptTestRoot>
  </PropertyGroup>
  ...
Вход в полноэкранный режим Выход из полноэкранного режима

2) Настройте среду модульного тестирования JavaScript. Например, чтобы использовать “mocha”, выполните следующие команды в терминальной консоли в каталоге тестового проекта.

(В качестве предпосылки в вашей среде должен быть установлен Node.js).

> npm init -y
> npm install --save-dev mocha
Войти в полноэкранный режим Выйти из полноэкранного режима

Не забудьте исключить папку “node_modules” из проекта юнит-тестов следующим образом:

<!-- A .csproj file of your unit test project -->
<Project Sdk="Microsoft.NET.Sdk">
  ...
  <!-- 👇 exclude the "node_modules" folder for any purpose. -->
  <ItemGroup>
    <Compile Remove="node_modules**" />
    <EmbeddedResource Remove="node_modules**" />
    <None Remove="node_modules**" />
  </ItemGroup>
  ...
Вход в полноэкранный режим Выход из полноэкранного режима

3) Напишите код вашего модульного теста в соответствии с используемым фреймворком модульных тестов JavaScript.

// ./tests/fooTest.js

const assert = require("assert");

describe("fooTest", function () {
    it('foo is bar', function () {
        assert.ok("this test will alwasy pass.");
    })
});
Войти в полноэкранный режим Выйти из полноэкранного режима

После этого вы увидите эти JavaScript юнит-тесты в Test Explorer, и сможете запускать их обычным для Visual Studio способом.

Для получения дополнительной информации, пожалуйста, смотрите также следующую ссылку на официальный сайт документа.

https://docs.microsoft.com/visualstudio/javascript/unit-testing-javascript-with-visual-studio?view=vs-2022&tabs=mocha

Написание кода тестов с помощью TypeScript

Конечно, мы можем написать коды тестов на JavaScript с помощью TypeScript. Например, для этого выполните следующие действия.

1) Установите NuGet-пакет “Microsoft.TypeScript.MSBuild” в проект модульного тестирования. Один из способов сделать это – выполнить команду dotnet add package в каталоге проекта модульного тестирования следующим образом:

> dotnet add package Microsoft.TypeScript.MSBuild
Войти в полноэкранный режим Выйти из полноэкранного режима

2) Добавьте файлы определения типов (.d.ts) для TypeScript-кода, который вам нужен, следующим образом:

> npm install --save-dev @types/mocha @types/node
Войти в полноэкранный режим Выйти из полноэкранного режима

3) Добавьте файл “tsconfig.json” со следующим содержимым в каталог проекта юнит-тестов для настройки поведения компилятора TypeScript. (Пожалуйста, настройте конфигурацию “target” в соответствии с вашими потребностями).

// ./tsconfig.json
{
  "compilerOptions": {
    "target": "ES2017",
    "module": "CommonJS",
    "strict": true
  },
  "compileOnSave": true
}
Войти в полноэкранный режим Выйти из полноэкранного режима

После этого вы сможете писать коды модульных тестов на TypeScript следующим образом:

// ./tests/fooTest.ts

import * as assert from "assert";
import { describe, it } from "mocha";

describe('fooTest', function () {
    it('foo is bar', function () {
        assert.ok("this test will always pass.");
    })
});
Войти в полноэкранный режим Выйти из полноэкранного режима

Проблема – несовместимая система модулей

Кстати, я также пишу вспомогательный JavaScript-код внутри библиотеки классов Razor – которая будет целью юнит-тестов в этом сценарии – на TypeScript.

И тип модульной системы у них должен быть “ES Module”, а не “CommonJS”, потому что эти JavaScript-коды будут вызываться из приложений Blazor с помощью IJSRuntime.InvokeAsync<IJSObjectReferense>("import", <путь .js файла>).

Например, tsconfig.json в проекте Razor Class Library будет выглядеть следующим образом.

// tsconfig.json in a Razor Class Library project
{
  "compilerOptions": {
    ...
    "module": "ES2015", // 👈 Use the ES Module system, not CommonJS.
    ...
Войти в полноэкранный режим Выйти из полноэкранного режима

А скомпилированный код JavaScript, например, “CatClass”, будет иметь следующий вид.

// catClass.js in the Razor Class Library project
export class CatClass {
    meows() {
        return "Meow!!";
    }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Но, к сожалению, “mocha” не работает с режимом ES Module на Visual Studio ожидаемо.
Я опущу подробности, но в любом случае, вы должны настроить коды модульных тестов для “mocha”, которые доступны для Visual Studio Test Explorer, на режим CommonJS.

Например, если у вас есть тестовый код, как показано ниже, который импортирует “catClass.js” в качестве тестовой цели,

// ./tests/catClassTest.ts in the unit test project
...
import { CatClass } from "../../RazorClassLibrary1/catClass";

describe('CatClass', function () {

    it('meows', function () {
        const cat = new CatClass();
        assert.equal('Meow!', cat.meows());
    });
});
Войдите в полноэкранный режим Выйти из полноэкранного режима

вы столкнетесь с ошибкой “SyntaxError: Unexpected token ‘export'”, когда Visual Studio попытается обнаружить юнит-тесты, подобные приведенным выше.
(На самом деле, сама “mocha” может работать с ES Module mode начиная с ver.9. Но нет никакого способа включить ES Module mode “mocha”, когда Visual Studio обнаруживает или запускает тесты, чтобы это не привело к ошибке).

Что делать?

Мое решение – оно сложное, но работает

К счастью, все мои JavaScript-коды написаны на исходных кодах TypeScript.
Поэтому я решил решить эту проблему, скомпилировав все файлы TypeScript в режиме модуля “CommonJS” в папку проекта юнит-теста, причем не только файлы для юнит-теста, но и файлы для тестовой цели.

Давайте посмотрим, что я сделал.

Прежде всего, я поместил файлы TypeScript юнит-теста в корневую папку проекта юнит-теста.
Это важно для одновременной компиляции TypeScript-файлов, включая как код модульного теста, так и код библиотеки (тестовой цели).
Конечно, я также настроил путь импорта модуля тестовой цели (файл TypeScript) в файлах TypeScript юнит-теста, вот так:

// move the ./tests/catClassTest.ts to ./catClassTest.ts
//   in the unit test project
...

// 👇 Fix the path of importing the test target module.

//import { CatClass } from "../../RazorClassLibrary1/catClass";
import { CatClass } from "../RazorClassLibrary1/catClass";
...
Вход в полноэкранный режим Выйти из полноэкранного режима

Далее я добавил две опции в конфигурацию компилятора TypeScript “tsconfig.json” в корневой папке проекта юнит-тестов.
Одна из них – добавление папки библиотеки классов Razor (она является тестовой целью) в папку compile target.
И еще один – это настройка выходной папки явно в соответствии со значением свойства <JavaScriptTestRoot> в файле проекта юнит-теста (.csproj).

// ./tsconfig.json in the unit test project
{
  "compilerOptions": {
    ...
    // 👇 Add these two options.
    "rootDirs": [ "./", "../RazorClassLibrary1" ],
    "outDir": "./tests",
    ...
Вход в полноэкранный режим Выход из полноэкранного режима

После того как я внес вышеуказанные изменения и пересобрал все решение, я получил результат, как показано на следующем рисунке.

Наконец, я смог правильно запустить JavaScript юнит-тесты в Visual Studio’s Test Explorer! 🎉

Заключение

Возможность запускать модульные тесты одновременно для C# и для JavaScript в Visual Studio Test Explorer UI очень удобна для меня при разработке библиотеки классов Razor для Blazor.

Но фреймворк для тестирования JavaScript “mocha” может работать только в режиме модуля CommonJS в Visual Studio Test Explorer, даже если тип модуля целевого JavaScript кода теста – ES Module.

К счастью, я всегда пишу код JavaScript на TypeScript, поэтому я решил эту проблему, дважды скомпилировав тестовые целевые файлы TypeScript в файлы JavaScript с разными модульными режимами (“ES Module” и “CommonJS”).

Пример кода был опубликован на репозитории GitHub по следующей ссылке:

https://github.com/sample-by-jsakamoto/Runs-JavaScript-tests-on-Visual-Studio-2022-Test-Explorer

Однако, на самом деле, я не уверен, что мое решение является лучшим.
Действительно, нет ли способа запустить “mocha” в режиме ES Module в Visual Studio Test Explorer?
Или же другой JavaScript фреймворк, такой как Jest, Jasmine и т.д., может позволить мне запустить его в режиме ES модуля?

Если у вас есть лучшее решение или идея, я буду благодарен, если вы поделитесь ими.

Учитесь, практикуйте, делитесь :).

Оцените статью
Procodings.ru
Добавить комментарий