Fitur SpecFlow yang Berguna

Halo semuanya!

Di Habré ada artikel bagus tentang SpecFlow. Saya ingin mempelajari topik ini dan berbicara tentang menjalankan tes secara paralel, meneruskan data di antara langkah-langkah, membantu helper, transformasi, kait, dan tentang menggunakan Json sebagai sumber data.

Eksekusi paralel dan transfer data antar langkah


Dalam dokumentasi untuk mentransfer data antar langkah, kami menemukan contoh berikut:

// Loading values into ScenarioContext ScenarioContext.Current["id"] = "value"; ScenarioContext.Current["another_id"] = new ComplexObject(); // Retrieving values from ScenarioContext var id = ScenarioContext.Current["id"]; var complexObject = ScenarioContext.Current["another_id"] As ComplexObject; 

Kode ini menggunakan kunci string. Menghafal dan mengetiknya cukup membosankan.

Masalah ini dapat diselesaikan dengan membuat kelas statis dengan properti yang diperlukan:

 public static class ScenarioData { public static ComplexObject Complex { get => ScenarioContext.Current.Get<ComplexObject>(nameof(Complex)); set => ScenarioContext.Current.Set(value, nameof(Complex)); } } 

Transfer data sekarang terlihat seperti ini:

 // Loading values into ScenarioContext ScenarioData.Complex = new ComplexObject(); // Retrieving values from ScenarioContext var complexObject = ScenarioData.Complex; 

Sayangnya, kami tidak akan dapat menggunakan ScenarioContext.Current saat menjalankan tes secara paralel hingga kami membuat Injeksi yang diperlukan

 //      [Binding] public abstract class ScenarioSteps { protected ScenarioSteps(ScenarioContext scenarioContext, FeatureContext featureContext) { FeatureContext = featureContext; ScenarioContext = scenarioContext; ScenarioData = new ScenarioData(scenarioContext); } public FeatureContext FeatureContext { get; } public ScenarioContext ScenarioContext { get; } public ScenarioData ScenarioData { get; } } //  ScenarioData public class ScenarioData { private readonly ScenarioContext _context; public ScenarioData(ScenarioContext context) { _context = context; } public ComplexObject Complex { get => _context.Get<ComplexObject>(nameof(Complex)); set => _context.Set(value, nameof(Complex)); } } //      [Binding] public class ActionSteps : ScenarioSteps { public ActionSteps(ScenarioContext scenarioContext, FeatureContext featureContext) : base(scenarioContext, featureContext) { } [When(@"user uses complex object")] public void WhenUserUsesComplexObject() { ScenarioData.Complex = new ComplexObject(); } } 

Dengan demikian, kami memecahkan beberapa masalah: menyingkirkan kunci string dan memberikan kemampuan untuk menjalankan tes secara paralel. Bagi yang ingin bereksperimen, saya membuat proyek kecil.

Bantu Pembantu dan Transformasi


Pertimbangkan langkah selanjutnya

 When user starts rendering | SourceType | PageOrientation | PageMediaSizeName | | set-01-valid | Landscape | A4 | 

Cukup sering, data dari tabel dikurangi seperti ini

 [When(@"user starts Rendering")] public async Task WhenUserStartsRendering(Table table) { var sourceType = table.Rows.First()["SourceType"]; var pageOrientation = table.Rows.First()["PageOrientation"]; var pageMediaSizeName = table.Rows.First()["PageMediaSizeName"]; ... } 

Menggunakan Assist Helpers, membaca data tes terlihat jauh lebih elegan. Kita perlu membuat model dengan properti yang sesuai:

 public class StartRenderingRequest { public string SourceType { get; set; } public string PageMediaSizeName { get; set; } public string PageOrientation { get; set; } } 

dan gunakan di CreateInstance

 [When(@"user starts Rendering")] public async Task WhenUserStartsRendering(Table table) { var request = table.CreateInstance<StartRenderingRequest>(); ... } 

Dengan Transformasi , deskripsi langkah uji dapat disederhanakan lebih jauh.

Tentukan transformasi:

 [Binding] public class Transforms { [StepArgumentTransformation] public StartRenderingRequest StartRenderingRequestTransform(Table table) { return table.CreateInstance<StartRenderingRequest>(); } } 

Sekarang kita bisa menggunakan tipe yang diinginkan sebagai parameter pada langkah:

 [When(@"user starts Rendering")] public async Task WhenUserStartsRendering(StartRenderingRequest request) { // we have implemented transformation, so we use StartRenderingRequest as a parameter ... } 

Bagi mereka yang ingin bereksperimen - proyek yang sama.

Mengaitkan dan menggunakan Json sebagai sumber data uji


Tabel SpecFlow lebih dari cukup untuk data uji sederhana. Namun, ada skenario pengujian dengan sejumlah besar parameter dan / atau struktur data yang kompleks. Untuk menggunakan data uji seperti itu, sambil mempertahankan keterbacaan skrip, kita membutuhkan Hooks . Kami akan menggunakan kait [BeforeScenario] untuk membaca data yang diperlukan dari file Json. Untuk melakukan ini, tentukan tag khusus di tingkat skrip

 @jsonDataSource @jsonDataSourcePath:DataSource\FooResponse.json Scenario: Validate Foo functionality Given user has access to the Application Service When user invokes Foo functionality | FooRequestValue | | input | Then Foo functionality should complete successfully 

dan tambahkan logika pemrosesan ke kait:

 [BeforeScenario("jsonDataSource")] public void BeforeScenario() { var tags = ScenarioContext.ScenarioInfo.Tags; var jsonDataSourcePathTag = tags.Single(i => i.StartsWith(TagJsonDataSourcePath)); var jsonDataSourceRelativePath = jsonDataSourcePathTag.Split(':')[1]; var jsonDataSourcePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, jsonDataSourceRelativePath); var jsonRaw = File.ReadAllText(jsonDataSourcePath); ScenarioData.JsonDataSource = jsonRaw; } 

Kode ini mengurangi isi file json (jalur relatif ke file) menjadi variabel string dan menyimpannya ke data skrip (ScenarioData.JsonDataSource). Dengan demikian, kita dapat menggunakan data ini jika diperlukan

 [Then(@"Foo functionality should complete successfully")] public void ThenFooFunctionalityShouldCompleteSuccessfully() { var actual = ScenarioData.FooResponse; var expected = JsonConvert.DeserializeObject<FooResponse>(ScenarioData.JsonDataSource); actual.FooResponseValue.Should().Be(expected.FooResponseValue); } 

Karena ada banyak data di Json, memperbarui data uji juga dapat diimplementasikan melalui tag. Mereka yang tertarik dapat melihat contoh di proyek yang sama .

Referensi


1. Mentimun
2. Gherkin
3. Dokumentasi SpecFlow
4. SpecFlow Wiki
5. Spesifikasi yang dapat dieksekusi: SpecFlow A hingga Z
6. Tes Data Driven & SpecFlow

Source: https://habr.com/ru/post/id449574/


All Articles