Cucumber-js: 提案cucumber-jsを実行するためのプログラムAPI

䜜成日 2021幎06月28日  Â·  29コメント  Â·  ゜ヌス: cucumber/cucumber-js

問題

珟圚、cucumber-jsをプログラムで実行する良い方法はありたせん。 必芁性は2぀の角床からです

  • cucumber-jsのテスト-CCKおよびプロゞェクトでの受け入れテスト甚
  • カスタムフォヌマッタヌずスニペットのテスト
  • フレヌムワヌクの䞀郚ずしおcucumber-jsを䜿甚するプロゞェクト䟋Serenity、Stryker

そのたた

珟時点で発生する傟向があるのは、 Cli新しいむンスタンスが䞀緒に匵られたargv入力で䜜成さ、パブリックAPIにも

時々おそらく䞊蚘の認識された脆匱性のためにフレヌムワヌクはcucumber-js CLIに䟝存するだけですが、統合しお独自のオプションを持぀方法を芋぀けるのに苊劎したす。

Runtimeクラスは珟圚パブリックAPIの䞀郚ですが、呌び出し元から提䟛されるピクルスずサポヌトコヌドによっおは、これらのコンテキストでは圹に立ちたせん。

提案

プロゞェクトの2぀のコンポヌネント

runCucumber

むンプロセスでテスト実行を実行する新しい非同期関数。 責任

  • 優れたむンタヌフェむスを備えたオプションオブゞェクトを受け入れる
  • ピクルスの解決、サポヌトコヌドの読み蟌み、テストケヌスの実行、フォヌマッタヌの調敎などの「䜜業」を行いたす
  • 結果に解決する玄束を返す

これはパブリックAPIの䞀郚であり、フレヌムワヌクのメンテナがcucumber-jsを「ラップ」するずきに䜿甚するこずをお勧めしたす。 たた、独自のテストにも䜿甚したす。

可胜な限り、 processずの盎接の察話を避け、代わりに、出力甚に正芏化されたオプションずストリヌムむンタヌフェむスを受け入れ、結果たたは未凊理の゚ラヌに基づいお終了する方法を決定するのは呌び出し元に任せたす。

たた、 Runtimeは実際には内郚的なものであるため、パブリックAPIから

CLI

事実䞊、 runCucumber 「クラむアント」。 責任

  • さたざたな゜ヌスargv、env vars、configファむルからのオプションを集玄したすコメントを参照
  • 解決されたオプションを䜿甚しおrunCucumberを呌び出したす
  • 結果に基づいお必芁に応じお終了したす

これは匕き続きパブリックAPIには含たれたせん。 たた、それは唯䞀の共通のパタヌンのようなプロゞェクトで今あるずしお、我々は簡単に、いく぀かの点で、独自のパッケヌゞにそれを砎るこずができ、そのようなこずを、公共のAPI䞊にある機胜/むンタフェヌスを䜿甚したす冗談。

このデカップリングは、内郚にブリヌドするこずなく、いく぀かの興味深い新しいCLI機胜ぞの道を開きたす。

  • キュりリ電子のもののための--gui
  • --interactiveは、TDDを実行する際のタヌゲットをすばやく再実行したす

等

たた、次の関数CLIや他のナヌザヌが䜿甚できるも公開したす。

  • オプションの取埗
  • i18nKeywordsずi18nLanguages

タむムスケヌル

これは、次の8.0.0リリヌスでタヌゲットにしおいたす。 今日からこれを始める準備ができおいたす。

breaking change enhancement

最も参考になるコメント

これは、出力ファむル名を必芁ずしないレポヌタヌに察しおどのように機胜したすか

formats: {
    stdout: './my-awesome-stryker-formatter',
    files: {
      'report.html': './my/fancy-reporter.js',
      'other-report.html': '@me/reporter-package',
    }
  },

stdoutストリヌムを䜿甚できるフォヌマッタヌは1぀だけです

党おのコメント29件

初期フィヌドバックのペヌゞング @aslakhellesoy @charlierudolph @ aurelien- reeves @mattwynne @nicojs @ jan-molak

私はこの提案が倧奜きです 停のキュりリのrunCucumberにはすでにこのようなAPIがありたす

@ davidjgoss-玠晎らしいですね

参考たでに、Serenity / JSが珟時点でCucumberを呌び出す方法は次のずおりです- CucumberCLIAdapter
そしお、これが構成パラメヌタヌをargvに倉換するロゞックです- CucumberOptions 。

argvの代わりにオプションオブゞェクトを提䟛できる方がはるかに良いでしょう👍🏻

倧奜きです

その新しいパブリックAPIを指定する䞀方で、問題1489で最近䜕が起こったのかを怜蚎し、パブリックAPIを提䟛しお、フィルタヌずテスト䞭の結果の機胜ずの盞互䜜甚をより良くするこずを怜蚎するこずもできたす。

それに加えお、Cucumber-Electronにずっおも簡単になるようなものを䜜りたしょう。

パブリックAPIを䜿甚する方が、䜕もないよりも優れおいるので、先に進んでください👍

できれば、 cucumber-jsず同じルヌルを䜿甚しおプロファむルをロヌドするAPIもあるので、通垞のcucumber-js呌び出しの正確な動䜜を暡倣できたす。

loadProfiles(directory = process.cwd()): Record<string, Profile>

StrykerJSは、 custom_formatters APIずeventBroadcasterによっお公開されたむベントにも倧きく䟝存したす。 それらをパブリックAPIにも远加できたすか 参照 https 

できれば、cucumber-jsず同じルヌルを䜿甚しおプロファむルをロヌドするAPIもあるので、通垞のcucumber-js呌び出しの正確な動䜜を暡倣できたす。

これは良い点です。 プロファむル少なくずも珟圚の圢匏ではは基本的にCLIに結合されおいるため、プロファむルを境界のその偎に保持するのは正しいず感じたすが、プロファむルをロヌドしお郚分的なオプションオブゞェクトを生成する関数を公開するこずもできたす。

その新しいパブリックAPIを指定する際に、問題1489で最近䜕が起こったのかを怜蚎し、テスト䞭のフィルタヌず結果の機胜ずの盞互䜜甚をより良くするためにパブリックAPIを提䟛するこずを怜蚎するこずもできたす。

APIを呌び出すずきにカスタムピクルスフィルタヌを提䟛するオプションを含めるこずができるず思いたす組み蟌みのフィルタヌを駆動する名前、タグなどに加えお。

非垞にコマンドラむン-yの堎合のプロファむルの珟圚の構文。

JSON、JavaScript、YAML、環境倉数など、より䞀般的な圢匏でプロファむルを指定できるようにするには、❀❀❀ず思いたす。 JSONでは、次のようになりたす。

.cucumber.json

{
  "default": {
    "requireModule": ["ts-node/register"],
    "require": ["support/**/*./ts"],
    "worldParameters": {
      "appUrl": "http://localhost:3000/",
    },
    "format": ["progress-bar", "html:./cucumber-report.html"]
  },
  "ci": {
    "requireModule": ["ts-node/register"],
    "require": ["support/**/*./ts"],
    "worldParameters": {
      "appUrl": "http://localhost:3000/",
    },
    "format": ["html:./cucumber-report.html"],
    "publish": true
  }
}

たたは、JavaScriptを䜿甚する

.cucumber.js

const common = {
  "requireModule": ["ts-node/register"],
  "require": ["support/**/*./ts"],
  "worldParameters": {
    "appUrl": "http://localhost:3000/",
  }
}

module.exports = {
  default: {
    ...common,
    "format": ["progress-bar", "html:./cucumber-report.html"]
  },
  ci: {
    ...common,
    "format": ["html:./cucumber-report.html"],
    "publish": true
  }
}

たたは、環境倉数たずえば、dotenvなどのツヌルを䜿甚しおロヌドされたものを䜿甚した堎合でも、次のようになりたす。

.cucumber.env

CUCUMBER_PROFILE_DEFAULT_REQUIREMODULE=ts-node/register
CUCUMBER_PROFILE_DEFAULT_REQUIRE=ts-node/register
CUCUMBER_PROFILE_DEFAULT_WORLDPARAMETERS_APPURL=http://localhost:3000/
CUCUMBER_PROFILE_DEFAULT_FORMAT=progress-bar,html:./cucumber-report.html
CUCUMBER_PROFILE_CI_REQUIREMODULE=ts-node/register
CUCUMBER_PROFILE_CI_REQUIRE=ts-node/register
CUCUMBER_PROFILE_CI_WORLDPARAMETERS_APPURL=http://localhost:3000/
CUCUMBER_PROFILE_CI_FORMAT=progress-bar,html:./cucumber-report.html
CUCUMBER_PROFILE_CI_PUBLISH=true

実際には、コンフィギュレヌションラむブラリヌは、たさにこれを行いたす。 他のものが邪魔になったため、Cucumber-JVMに統合するこずは決しおありたせんでしたが、JavaScriptの実装で詊しおみるこずができるでしょうか

@aslakhellesoyはそれが玠晎らしいだろうず同意したす この提案にPOCを導入しお、もう少し具䜓的に話し合うこずができるようにしたす。その䞀環ずしおプロファむルを䜜成したいず思いたす4。5幎、751を頌りに😄

参照。 1004

これは良い点です。 プロファむル少なくずも珟圚の圢匏ではは基本的にCLIに結合されおいるため、プロファむルを境界のその偎に保持するのは正しいず感じたすが、プロファむルをロヌドしお郚分的なオプションオブゞェクトを生成する関数を公開するこずもできたす。

はい、プラグむン䜜成者の芳点からすれば、それは玠晎らしいこずであり、非垞にありがたいこずです。

JSON、JavaScript、YAML、環境倉数など、より䞀般的な圢匏でプロファむルを指定できるようにするには、❀❀❀ず思いたす。 JSONでは、次のようになりたす。

それはいいです たた、cucumberJSず同じ方法でAPIをロヌドしおいただければ幞いです。 単䞀のcucumber.jsファむルをロヌドするのは簡単です。 優先順䜍、ファむル圢匏などを含む構成ファむルの読み蟌みアルゎリズムを耇補し、それを維持するこずはたったく別のこずです😅。

Q必芁なキャッシュをクリアせずにrunCucumber 2回続けお実行できたすか これは、ミュヌテヌションテストのナヌスケヌスにずっお重芁です。

アクティブなミュヌタントを切り替えるために、グロヌバル倉数を倉曎しながら、環境をロヌドし、テストをすばやく連続しお耇数回実行したいず考えおいたす。

珟圚、 cliプラむベヌトAPIを䜿甚しおおり、各テスト実行の間にrequire.cacheからステップ定矩ファむルをクリアする必芁がありたす。 これはCommonJSには理想的ではなく、esmではたったく機胜したせん。

ナヌスケヌスの擬䌌コヌド

const profiles = await loadProfiles();
const options = {
  ...profiles.default,
  formatter: require.resolve('./our-awesomely-crafted-formatter'),
  some: 'other options we want to override',
}
const cucumber = new Cucumber(options);

// Allow cucumber to load the step definitions once. 
// This is `async`, so support for esm can be added without a breaking change
await cucumber.initialize();

// Initial test run ("dry run"), without mutants active
await cucumber.run();

collectMutantCoveragePerTestFromFormatter();

// Start mutation testing:

global.activeMutant = 1;
await cucumber.run({ features: ['features/a.feature:24']);
collectResultsFromFormatterToDetermineKilledOrSurvivedMutant()

global.activeMutant = 2;
await cucumber.run({ features: ['features/b.feature:24:25:26', 'features/c.feature:12']);
collectResultsFromFormatterToDetermineKilledOrSurvivedMutant()

// etc

@nicojsは間違いなくこれが必芁であるこずに同意したす。たずえば、ラムダでキュりリを実行したい人が数回登堎したす。たた、これも必芁になるむンタラクティブモヌドを远加したいず思いたす。

私がこれたでにスケッチしたのは、より機胜的なスタむルでしたが、私が思うのず同じ基本的な抂念でした。

const runnerOptions = {
    support: {
        require: ['features/support/**/*.js']
    }
}

// initial run returns support code library
const { support } = await runCucumber(runnerOptions)

// subsequent run reuses support code library
await runCucumber({
    ...runnerOptions,
    support
})

それは私たちのために働きたす👍

私たちにも圹立ちたす👍🏻

このようなものは、テストツヌルの統合Jest、Cypressで今日発生しおいる倧きな混乱の代替手段ずしお非垞に圹立぀ず思いたす。たずえば、これらの問題を重芁床の高い順に芋぀けたした。

  • cypress-cucumber-preprocessorは、䟋のタグをサポヌトしおいたせんhttps://github.com/TheBrainFamily/cypress-cucumber-preprocessor/issues/196
  • jest-cucumberはCucumber JSONレポヌトをサポヌトしおいたせんhttps://github.com/bencompton/jest-cucumber/issues/27
  • cypress-cucumber-preprocessorは、集蚈を公匏にサポヌトしおいない耇数のCucumber JSONレポヌトを生成したすhttps://github.com/TheBrainFamily/cypress-cucumber-preprocessor/issues/423
  • jest-cucumberはjest-cucumber-fusionほど䟿利ではありたせん
  • cucumber-jestたす...
  • Karmaにはもう機胜する実装がありたせんhttps://github.com/cucumber/cucumber-js/issues/1095

Jest / Karma / Cypress /などの間に最小限のグルヌコヌドが衚瀺されたす。 ずcucumber-jsなので、䜿甚する必芁のある

玠晎らしい提案@davidjgoss👍

コマンドラむンナヌザヌむンタヌフェむスず、テストずしおシナリオを解析および実行する「ビゞネスロゞック」ずの間の関心の分離は、ヘキサゎナルアヌキテクチャパタヌンを思い出させたす。

cucumber-rubyでは、「クリヌンルヌム」でれロから再構築しおいたため、実際にはコアドメむンロゞックたたは「内郚六角圢」を別のgemパッケヌゞに分割したした。 これはここでのコンテキストではないこずは理解しおいたすが、この蚭蚈からむンスピレヌションを埗たり、RubyAPIにむノベヌションをフィヌドバックしたりする䟡倀があるかもしれたせん。 cucumber-ruby-core gemのREADMEに、そのAPIの䜿甚方法の䟋がありたす。

さお、これが「実行」ビットのAPI眲名の最初のパスです。 これは、内郚にあるIConfigurationオブゞェクトに倧きく基づいおいたすがしたがっお、䞋の方にリファクタリングをあたり匕き起こさないようにする必芁がありたす、「フラット」は少し少なくなりたす。

export interface IRunCucumberOptions {
  cwd: string
  features: {
    defaultDialect?: string
    paths: string[]
  }
  filters: {
    name?: string[]
    tagExpression?: string
  }
  support:
    | {
        transpileWith?: string[]
        paths: string[]
      }
    | ISupportCodeLibrary
  runtime: {
    dryRun?: boolean
    failFast?: boolean
    filterStacktraces?: boolean
    parallel?: {
      count: number
    }
    retry?: {
      count: number
      tagExpression?: string
    }
    strict: boolean
    worldParameters?: any
  }
  formats: {
    stdout: string
    files: Record<string, string>
    options: IParsedArgvFormatOptions
  }
}

export interface IRunResult {
  success: boolean
  support: ISupportCodeLibrary
}

export async function runCucumber(
  options: IRunCucumberOptions
): Promise<IRunResult> {
  // do stuff
}

そしお、非垞に工倫された䜿甚䟋

const result = await runCucumber({
  cwd: process.cwd(),
  features: {
    paths: ['features/**/*.feature'],
  },
  filters: {
    name: ['Acme'],
    tagExpression: '<strong i="10">@interesting</strong>',
  },
  support: {
    transpileWith: ['ts-node'],
    paths: ['features/support/**/*.ts'],
  },
  runtime: {
    failFast: true,
    retry: {
      count: 1,
      tagExpression: '<strong i="11">@flaky</strong>',
    },
    strict: true,
    worldParameters: {
      foo: 'bar',
    },
  },
  formats: {
    stdout: '@cucumber/pretty-formatter',
    files: {
      'report.html': 'html',
      'TEST-cucumber.xml': 'junit',
    },
    options: {
      printAttachments: false,
    },
  },
})

フィヌドバックを歓迎したす これは、別の機胜ずなるプロファむル/構成のロヌドに関するものをカバヌしおいないこずに泚意しおください。

これはよさそうだず思いたす。 質問カスタムフォヌマッタヌをどのように構成したすか

@nicojsはCLIのようなものです

formats: {
    files: {
      'report.html': './my/fancy-reporter.js',
      'other-report.html': '@me/reporter-package',
    }
  },

この@davidjgossの進捗状況を確認できおうれしいです。

これの進行を遅らせたくはありたせんが、同時に、他のCucumber実装でも機胜する圢匏を採甚するようにしたいです。

最終的にはJSONスキヌマですが、それに぀いお説明しおいる間、TypeScriptタむプは人間が解析しやすいず思いたす。

cucumber/commonモノレポで提案されたフォヌマットに関する新しい問題を䜜成し、コアチヌムにそこで議論するよう招埅するこずをお勧めしたす。

@aslakhellesoyが行いたす。

プログラマティックAPIが共通のオプション構造に関連付けられおいないこずに぀いおどう思いたすか それからrunCucumberオプションにマップするように。 少し耇雑になるかもしれたせんが、ロヌドするパラメヌタであるsupportブロック、たたは以前にロヌドされたサポヌトコヌドラむブラリがあるなどの理由で魅力的です。 機胜+ピクルスに぀いおも同様のこずができたす。 たた、CLIでサポヌトするさたざたなオプション䟋 --exit がありたすが、プログラマティックAPIでは適切ではありたせん。

プログラマティックAPIが共通のオプション構造に関連付けられおいないこずに぀いおどう思いたすか

オプションファむルの内容からrunCucumberが必芁ずするデヌタ構造に倉換する関数を提䟛する限り、それは問題ないず思いたす。

最終的にはJSONスキヌマですが、それに぀いお説明しおいる間、TypeScriptタむプは人間が解析しやすいず思いたす。

なぜ遞択する必芁があるのですか StrykerJSでJSONスキヌマを䜿甚しお、 json-schema-to-typescriptを䜿甚しおtypescriptを生成しおいprebuildステップを䜿甚しおオンザフラむで生成したす。

JSONスキヌマは、人間のIMOにずっおはただある皋床読みやすいものです。 ストラむカヌレポにはすでにPRがあり、人々は䜕をすべきか知っおいるようです🀷‍♀

CLIのように

formats: {
    files: {
      'report.html': './my/fancy-reporter.js',
      'other-report.html': '@me/reporter-package',
    }
  },

これは、出力ファむル名を必芁ずしないレポヌタヌに察しおどのように機胜したすか そのようです

formats: {
  files: {
    '': require.resolve('./my-awesome-stryker-formatter')
  }
}

なぜ遞択する必芁があるのですか

構成の構造の信頌できる唯䞀の情報源ずしおJSONスキヌマを䜿甚する必芁があるず思いたす。 -次に、そのスキヌマからTypeScript / Java / Whateverコヌドを生成したす。

しかし、JSONスキヌマは人間にずっおは少し読みにくいので、 cucumber/common GitHubの問題でスキヌマに぀いお議論しおいる間、私は

私が䜕を意味するのか分かりたすか

JSONスキヌマは、人間のIMOにずっおはただある皋床読みやすいです。

私にはわかりたせん:-)冗長すぎたす。

これは、出力ファむル名を必芁ずしないレポヌタヌに察しおどのように機胜したすか

formats: {
    stdout: './my-awesome-stryker-formatter',
    files: {
      'report.html': './my/fancy-reporter.js',
      'other-report.html': '@me/reporter-package',
    }
  },

stdoutストリヌムを䜿甚できるフォヌマッタヌは1぀だけです

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡