簡體   English   中英

通過REST API將測試結果發布到TFS 2018測試用例

[英]Publishing test results to TFS 2018 test cases via REST API

目前,我們使用mstest.exe運行自動化測試,然后創建.trx結果文件。 然后,在此之后,我們使用tcm.exe將這些結果發布到TFS服務器上的某些測試套件/測試用例。

我們希望不再使用tcm並使用TFS REST API從我們的.trx結果文件中發布結果。

我已經閱讀了關於REST API的一些文檔 ,但沒有具體使用TFS擴展客戶端類(例如TestManagementHttpClient ),它只列舉了要使用的實際URL。 它也沒有提供很多關於它所期望的參數的例子。

有一些Microsoft.TeamFoundation.TestManagement.WebApi命名空間的官方.NET參考文檔 ,它有點幫助,但同樣沒有任何示例/示例來了解每個函數所期望的參數。

我能夠找到唯一示例/示例並不詳細,我不能理解如何在我的情況下應用它,因為我不熟悉測試點/測試的概念來操縱代表它們的類。

我猜測試運行有多個測試點(每個測試用例運行一個?),表示執行該測試用例的結果? 在這種情況下,我應該假設我需要為每個測試結果創建一個測試點。 如果是這樣,我如何知道提供哪個ID? 上面的示例硬編碼“3”作為其值。

如果有人可以解釋上面的示例,並提供一個更好/更完整的與我的用例相關的(從.trx文件,並將這些結果發布到與特定測試套件下的鏈接自動化項匹配的測試用例),幫助我理解一切如何相互關聯,我將不勝感激。

謝謝。

所以基於我在我的問題中鏈接的示例/示例來回答我自己的問題:

  1. 您需要使用TestManagementHttpClient.GetTestConfigurationsAsync()獲取所需的測試配置

  2. 然后,您需要使用TestManagementHttpClient.GetPointsAsync()獲取該測試用例/測試配置組合的所有測試點

  3. 然后,您需要創建一個測試運行。 這是通過至少指定先前獲取的測試點ID來聲明新的RunCreateModel對象來完成的。 您可能還需要填寫大量參數( buildIdisAutomated等)。 然后,您需要調用TestManagementHttpClient.CreateTestRunAsync()來實際創建它。

  4. 對於您在創建時指定的每個測試點,步驟3實際上在測試運行下創建了空測試結果。 您需要使用TestManagementHttpClient.GetTestResultsAsync()獲取它們並使用TestCaseResult.TestCase.Id屬性修改它們的Outcome屬性,以了解哪個結果適用於哪個測試用例。 您還可能希望填寫其他屬性,例如State等。再次,您需要使用TestManagementHttpClient.UpdateTestResultsAsync()將這些修改推送到TFS。

  5. 最后一步是通過創建state = "Completed"RunUpdateModel對象,然后調用TestManagementHttpClient.UpdateTestRunAsync()將測試運行設置為已完成

這是我寫完的所有功能的函數,用F#編寫:

// A test point is a pairing of a test case with a test configuration
let createTestRun (httpClient:TestManagementHttpClient) (testRunName:string) (teamProjectName:string) (testPlanId:int) (testSuiteId:int) (testCaseIdsAndResults:seq<(int * string)>) (buildId:int) (cancellationToken:CancellationToken) = async {
    let testPlanIdString = testPlanId.ToString()
    let plan = new ShallowReference(testPlanIdString)

    let! testConfigurations = httpClient.GetTestConfigurationsAsync(teamProjectName, cancellationToken = cancellationToken) |> Async.AwaitTask
    let defaultTestConfiguration = testConfigurations |> Seq.find (fun c -> c.IsDefault) // TODO: We only use the default configuration for now. Do we always want this?

    let rec getTestPoints (testIdsAndResults:(int * string) list) (testPoints:TestPoint[]) = async {
        match testIdsAndResults with
        | (testId, _)::rest ->
            let! fetchedTestPoints = httpClient.GetPointsAsync(teamProjectName, testPlanId, testSuiteId, testCaseId = testId.ToString(), cancellationToken = cancellationToken) |> Async.AwaitTask
            let testPoint = fetchedTestPoints |> Seq.find (fun p -> p.Configuration.Id = defaultTestConfiguration.Id.ToString())
            let newTestPointsList = Array.append testPoints [|testPoint|]
            return! getTestPoints rest newTestPointsList
        | _ ->
            return testPoints
    }
    let! testPoints = getTestPoints (List.ofSeq testCaseIdsAndResults) Array.empty
    let testPointIds = testPoints |> Array.map (fun p -> p.Id)

    let runCreateModel = new RunCreateModel(name = testRunName, plan = plan, buildId = buildId, isAutomated = new Nullable<bool>(true), pointIds = testPointIds)
    let! testRun = httpClient.CreateTestRunAsync(runCreateModel, teamProjectName, cancellationToken = cancellationToken) |> Async.AwaitTask
    let! emptyResults = httpClient.GetTestResultsAsync(project = teamProjectName, runId = testRun.Id, outcomes = new List<TestOutcome>(), cancellationToken = cancellationToken) |> Async.AwaitTask

    let rec createCaseResults (testIdsAndResults:(int * string) list) (results:TestCaseResult[]) = async {
        match testIdsAndResults with
        | (testId, testResult)::rest ->
            let caseResult = emptyResults |> Seq.find (fun r -> r.TestCase.Id = testId.ToString())
            caseResult.State <- "Completed"
            caseResult.Outcome <- testResult // "passed", "failed", "never run", "not applicable"
            let newResultsList = Array.append results [|caseResult|]
            return! createCaseResults rest newResultsList
        | _ ->
            return results
    }
    let! results = createCaseResults (List.ofSeq testCaseIdsAndResults) Array.empty
    let! _ = httpClient.UpdateTestResultsAsync(results, teamProjectName, testRun.Id, cancellationToken = cancellationToken) |> Async.AwaitTask

    let runmodel = new RunUpdateModel(state = "Completed");
    let! _ = httpClient.UpdateTestRunAsync(runmodel, teamProjectName, testRun.Id, cancellationToken = cancellationToken) |> Async.AwaitTask

    ()
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM