Я пытаюсь запустить команду dotnet test
для определенных тестовых проектов в конвейере devops MS Azure.
Это работает:
- script: |
dotnet test "./Project One/Project One Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
dotnet test "./Project Two/Project Two Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
displayName: 'run tests in cascade'
Я не хочу указывать имена проектов, только какое-то правило (имя проекта должно заканчиваться на «UnitTests», «Unit Tests» или «Unit_Tests»), но dotnet test <PROJECT>
не допускает подстановочных знаков.
Похоже, что подстановочные знаки работают с dotnet test <DLL>
(./**/*Unit?Tests.dll), но не работают, потому что не находят файл deps.json в папке obj.
Мое решение состоит в том, чтобы пройтись по отфильтрованному списку файлов проекта:
for proj in ./**/*Unit?Tests.*proj
do
dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
done
Он запускает тесты, но отличается от каскадных вызовов, здесь, когда тест проекта терпит неудачу, он не завершается ошибкой шага, поэтому конвейер не останавливается!
Я попытался получить результат из прогона, но безуспешно (это не работает):
for proj in ./**/*Unit?Tests.*proj
do
result=$(dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY")
if result = 1
then
exit 1
fi
done
Любое предложение?
Почему, когда dotnet test
терпит неудачу (выход 1), шаг не терпит неудачу?
Я попытался ввести в цикл только неудачный тестовый проект, и в этом случае он не работает.
[ОБНОВЛЕНИЕ]
Полный пайплайн.yaml:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
project file: "Alex75.MySolution/Alex75.MyProject.fsproj"
steps:
- script: dotnet build -c Release
displayName: 'Build'
- script: |
dotnet test "./ProjectTwo Unit Tests/ProjectTwo Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
dotnet test "./ProjectOne Tests/ProjectOne Unit Tests.fsproj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
displayName: 'Test'
condition: false
- script: |
for proj in ./**/*Unit?Tests.*proj
do
echo "run tests in $proj"
dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
done
displayName: 'Test (Unit Test projects)'
condition: true
- powershell: |
$URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/logs?api-version=5.1"
Write-Host "URL = $URL"
$logs = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $(PAT)"} -Method Get
$lastLogId = $Logs.value[$Logs.value.count-1].id
Write-Host "lastLogId = $lastLogId"
$URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/logs/$lastLogId?api-version=5.1"
$result = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $(PAT)"} -Method Get
Write-Host $result
Write-Host "Start Check result..."
$lines = $result.Split([Environment]::NewLine)
foreach($line in $lines) {
if ($line -match "Failed!")
{
throw 'dotnet test fails ($line)'
}
}
Write-Host "Test result check completed."
displayName: 'Check tests result'
На примере @vito-liu-msft я попытался проверить журналы тестов, чтобы проверить ошибку.
Здесь только скрипт powershell:
$URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/logs?api-version=5.1"
Write-Host "URL = $URL"
$logs = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $(PAT)"} -Method Get
$lastLogId = $Logs.value[$Logs.value.count-1].id
Write-Host "lastLogId = $lastLogId"
$URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/logs/$lastLogId?api-version=5.1"
$result = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $(PAT)"} -Method Get
Write-Host $result
Write-Host "Start Check result..."
$lines = $result.Split([Environment]::NewLine)
foreach($line in $lines) {
if ($line -match "Failed!")
{
throw 'dotnet test fails ($line)'
}
}
Write-Host "Test result check completed."
PAT — это токен личного доступа, поскольку он создается, его не нужно преобразовывать
прежде чем использовать его в HTTP-запросе.
LogId недоступен, поэтому есть запрос на получение коллекции журналов, а затем второй запрос на получение конкретного последнего журнала (ответ кажется упорядоченным по дате, возможно, стоит перепроверить).
Обратите внимание, что если второй запрос вернет 404, 500 или другой результат (не сбой), проверка ошибок не найдет фактических ошибок! Требуется надлежащая проверка ответа.
Я проверил -match "Failed!" в PowerShell, но я не тестировал команду throw в конвейере, потому что...
Потратив столько времени на то, чтобы понять, как читать и проверять журналы, создайте отдельный скрипт PowerShell, я обнаружил, что первоначальное простое решение работает!
Да, сборка завершается неудачно из-за сбоя теста (он также показывает точную ошибку, указывающую на проблему), и шаг завершается неудачно.
(поэтому следующий шаг, проверка результатов теста, пропускается!)
Я думаю, что я должен был сделать некоторую ошибку раньше при фильтрации тестовых проектов, чтобы сбойный проект не запускался (и не вызывал никаких ошибок), поэтому я подумал, что это не «перехват» ошибки, и сборка не остановилась.
Возможно, я смешал 2 разных файла конвейера, пока менял его.
В любом случае это инкриминируемый шаг (сценарий):
for proj in ./**/*Unit?Tests.*proj
do
echo "run tests in $proj"
dotnet test "$proj" -c Release --no-build --filter "TestCategory!=SKIP_ON_DEPLOY & TestCategory!=REQUIRES_API_KEY"
done
В списке с эхом можно увидеть, какие тестовые проекты используются.
Честно говоря, все еще ищу что-нибудь попроще, но обязательно посмотрю через пару дней. Спасибо.
когда тест проекта терпит неудачу, он не проваливает шаг, поэтому конвейер не останавливается! Почему при сбое теста dotnet (выход 1) шаг не завершается ошибкой?
В качестве обходного пути мы можем получить dotnet test
идентификатор журнала задач через этот rest API, добавить задачу power shell
и ввести приведенный ниже скрипт для анализа dotnet test
журнала. нам нужно ввести код совпадения, например fails (exit 1)
. Если тест dotnet не пройден, конвейер остановится.
Мы должны добавить PAT в переменную и установить ее в секрет, а затем использовать ее в скрипте.
$connectionToken = "{PAT}"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$URL = "https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/logs/{logId}?api-version=6.1-preview.2"
$Result = Invoke-RestMethod -Uri $URL -Headers @{authorization = "Basic $base64AuthInfo"} -Method Get
Write-Host $result
$lines = $result.Split([Environment]::NewLine)
$passed = 0;
$failed = 0;
foreach($line in $lines) {
if ($line -match "{match sentence}") {
throw 'dotnet test fails (exit 1)'
}
}
Обновление1
как я могу найти "logId"?
Мы могли бы использовать этот REST API для проверки logId
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/logs?api-version=6.1-preview.2
Результат:
И мне действительно нужно использовать «предварительную» версию API?
Мы также могли бы использовать другую версию, например 5.1, мы могли бы изменить версию REST API в документе, вы можете проверить рисунок ниже.
Я создал токен личного доступа и переменную с именем «PAT» в сборке конвейера. Несмотря на то, что в документации сказано: Пакетный сценарий: %VARIABLE-NAME% PowerShell script: ${env:VARIABLE-NAME} Bash script: $(VARIABLE-NAME) на самом деле, чтобы заставить его работать в сценарии PowerShell, мне пришлось использовать $(VARIABLE NAME ). Хорошо, я создаю URL-адрес: $URL = "$(System.CollectionUri)/$(System.TeamProject)/_apis/build/builds/$(Build.BuildNumber)/logs/{logId}? api-version=6.1-preview.2" Предполагая, что «buildId» правильный, как я могу найти «logId»? И мне действительно нужно использовать «предварительную» версию API?
Привет @ Alex75, я обновил ответ, пожалуйста, проверьте его.
Привет, есть какие-нибудь новости об этом билете? Не стесняйтесь, дайте мне знать, если у вас есть какие-либо вопросы. Если ответ может помочь, вы можете принять его. Спасибо
Привет! Просто проверяю, блокирует ли тебя эта проблема? Любое обновление для этой проблемы?