3. О чем будем говорить
• Что такое Zephyr и Structure
• Зачем дружить Zephyr и Structure
• Как влезть в JIRA скриптами
• Как влезть в БД JIRA
• Как влезть в форматирование страниц
• Как этим всем сделать всем хорошо
• Как этого не делать
• …и о муми-троллях…
4. Structure – как все красиво организовать
marketplace.atlassian.com/plugins/com.almworks.jira.structure
5. Zephyr - как выглядят тесты
marketplace.atlassian.com/plugins/com.thed.zephyr.je
8. Проблема
• Тест и прогон теста – разные сущности
• Статусы тестов – поля прогона теста, а не теста
• Нужен механизм проброса статуса теста на уровень теста
• Статус теста может быть разным в разных версиях/прогонах
• Выход – поля
• Latest test status
• Latest test execution
12. Как попробовать извлечь данные
marketplace/plugins/info.renjithv.jira.plugins.sysadmin.homedirectorybrowser
13. Вариант реализации: из базы
def delegator =
ComponentAccessor.getComponent(DelegatorInterface)
String helperName = delegator.getGroupHelperName("default");
StringBuffer sb = new StringBuffer()
def sqlStmt = ”...";
Connection conn =
ConnectionFactory.getConnection(helperName);
Sql sql = new Sql(conn)
sql.eachRow(sqlStmt) {
sb << "${it.status}”
def statusName = status[sb.toString()][0]
}
14. Как выбрать данные в скрипте
sqlStmt = "SELECT issue_id FROM ao_7deabf_schedule
where project_id = " + projectId + " and
(date_created between '" + timestamp.format(10.minutes.ago) +
"' and '" + timestamp.format(0.minutes.from.now) + "'
or executed_on between '" + (unixTime -
10*60*1000).toString() + "' and '" + unixTime.toString() +
"')
order by date_created desc";
15. Почему данные неактуальны?
• У Zephyr нет событий, означающих обновление test run
• JIRA кеширует значения атрибутов
• Поиск JQL работает исходя из кэша
• Частичное обновление кэша работает на весь проект
• Решение – периодическая перестройка кэша
16. Реиндекс и поиск: правильно,
но не работает
• Проблема: При попытке искать по кастом полям ничего не
находится или находится не все или не сразу
• Решение: само пройдет.
• Не проходит
• Решение: enableCache = {-> false}
• Не дает искать в принципе
20. А еще хотим выполнять тесты…
SELECT s.status, v.vname, s.id
FROM ao_7deabf_schedule s, projectversion v
WHERE s.project_id=" + projectId +
" and s.issue_id=" + issueId +
" and s.version_id = v.id
order by s.date_created desc
limit 1";
21. А еще хотим выполнять тесты…
if (!versionName.equals("") &&
(statusName.equals("UNEXECUTED") ||
statusName.equals("IN PROGRESS")) ) …
<a href="/secure/enav/#/" + executionId + "">
<span
class="trigger-label">Continue exec
</span>
</a>
22. А еще хотим выполнять тесты…
if (versionName.equals("")
<a id="zephyr-je-add-execute"
title="Execute Test"
class="toolbar-trigger viewissue-add-execute”
href="/secure/AddExecute!AddExecute.jspa?id=" +
issueId + "">
<span class="trigger-label">Exec new
</span>
</a>
23. Что делать с форматированием и поиском
coloredStatus = ”
<div class="labels exec-status-container">
<dd style="background-color: " +
statusColor + "">” + statusName +
"</dd></div>";
status = statusName
25. А еще хотим экспорт тест-плана в документ
• Поле Preview, которое начинается с </td>
retStr += "</td></tr><tr style="width: 100%;">
<td colspan="10" style="font-size: 10pt;">”
retStr += wikiRenderer.render(issue.getDescription(), null)
retStr += "<br/>"