Публикация результатов теста в тестовых примерах TFS 2018 через REST API - PullRequest
0 голосов
/ 30 января 2019

В настоящее время мы запускаем наш автоматический тест с использованием mstest.exe, который затем создает файл результатов .trx.Затем, после этого, мы публикуем эти результаты с помощью tcm.exe в некоторых наборах тестов / тестовых случаях на нашем TFS-сервере.

Мы хотели бы отказаться от использования tcm и опубликовать результаты из нашего файла результатов .trx, используяAPI REST TFS.

Я прочитал некоторые из документации по API REST относительно этого, но нет ничего конкретного для использования классов расширенного клиента TFS (например, TestManagementHttpClient),он только перечисляет фактические URL для использования.Он также не дает много примеров того, какие параметры он ожидает.

Существует официальная справочная документация .NET для пространства имен Microsoft.TeamFoundation.TestManagement.WebApi, которая немного помогает., но опять же у него нет примеров / примеров, чтобы узнать, какие параметры ожидает каждая функция.

Единственный пример / образец , который мне удалось найти , был недостаточно детализирован, чтобы я мог понятькак применять его в моей ситуации, поскольку я недостаточно знаком с концепциями контрольных точек / тестовых запусков, чтобы манипулировать классами, которые их представляют.

Я предполагаю, что в тестовом прогоне есть несколько тестовых точек (по одной на каждый тестовый случай?), Представляющих результат выполнения этого тестового примера?В этом случае я должен предположить, что мне нужно будет создать одну контрольную точку для каждого результата теста.Если так, как я узнаю, какой ID дать?В приведенном выше примере в качестве значения указываются жесткие коды «3».

Если кто-то может объяснить приведенный выше пример и предоставить лучший / более полный пример, относящийся к моему варианту использования (из файла .trx и публикации этих результатов).я был бы очень признателен, если бы тестовые случаи соответствовали связанному элементу автоматизации в определенном наборе тестов), помогая мне понять, как все соотносится друг с другом.

Спасибо.

1 Ответ

0 голосов
/ 01 февраля 2019

Итак, чтобы ответить на мой собственный вопрос, основываясь на примере / образце, который я привел в своем вопросе:

  1. Вам необходимо получить нужную конфигурацию теста, используя TestManagementHttpClient.GetTestConfigurationsAsync()

  2. Затем вы захотите получить все контрольные точки для этой комбинации тестовый набор / конфигурация теста, используя TestManagementHttpClient.GetPointsAsync()

  3. Затем вам необходимо создать тестовый прогон,Это делается путем объявления нового объекта RunCreateModel на не менее с указанием идентификаторов контрольных точек, которые вы предварительно выбрали.Также вы можете заполнить множество параметров (buildId, isAutomated и т. Д.).Затем вам нужно вызвать TestManagementHttpClient.CreateTestRunAsync() для его фактического создания.

  4. Шаг 3 фактически создал пустые результаты теста при выполнении теста для каждой контрольной точки, которую вы указали при ее создании.Вам нужно получить их, используя TestManagementHttpClient.GetTestResultsAsync() и изменить свойство Outcome, используя свойство TestCaseResult.TestCase.Id, чтобы узнать, какой результат для какого тестового примера.Вы также можете указать другие свойства, такие как State и т. Д. Опять же, вам нужно отправить эти изменения в TFS, используя TestManagementHttpClient.UpdateTestResultsAsync()

  5. Последний шаг - настроитьВыполнение теста завершено созданием RunUpdateModel объекта с state = "Completed" и последующим вызовом 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

    ()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...