Внесу свою крупицу опыта.
У нас была потребность конвертировать xls в pdf. Перепробовав кучу вариантов в итоге остановились на LibreOffice и jodconverter (немного допиленный под наши нужды). Выбрали именно LibreOffice, а не OpenOffice, т.к. последний плохо работал под виндой, а у нас разработка шла под Win, а эксплуатация под Linux. Но оба имели одни и тебе проблемы — периодически падали. И не понятно почему — просто в один момент завершались и всё, без записи чего либо в лог. Потратив кучу времени ничего не нашли (может на тот момент опыта не хватило). В итоге сделали топорное но надёжное решение — скрипт периодически мониторит наличие процесса LibreOffice и если не находит, то запускает. С этим скриптом система работает уже 3 года :)
Потом, присоединяюсь к товарищу asm0dey — можно каждый раз не запускать соединение. У нас оно единожды запускалось, но, т.к. иногда LibreOffice перезагружался (см. выше), то непосредственно перед конвертацией проверялось, что соединение есть и, если нет, устанавливалось. Но тут маленькое примечание — нам не нужна была многопоточность при конвертации, поэтому конвертация была synchronize — каждый поток, которому нужно было конвертировать, ждал своей очереди. Т.ч. singletone соединения нам было достаточно.
Плюс ещё комментарий на тему jodconverter — т.к. он сейчас не поддерживается (насколько я понял), то всегда можно конвертировать самими средствами LibreOffice — примеры есть на сайте. Там ничего сложного нет, только будет немного больше кода. Т.е. jodconverter — это просто надстройка над стандартными средствами конвертации, которая упрощает типовые задачи по конвертации. И ничего более. Так что от него можно будет при надобности отказаться.
А хотя бы порядок времени можете назвать? В этом году или в следующем? А то я как активный пользователь IDEA (Pro версии) и пишущий иногда на C++ не могу пользоваться ничем иным :)
При этом похоже на наш подход с единственным отличием — у вас страницы представлены статическими объектами и при написании тестов пользователь не думает о времени жизни страницы и пишет сценарий последовательно по шагам.
Да, у нас так получилось, что большинство PageObject не нужно было каждый раз заново создавать, но в паре мест, где PageObject должен знать в контексте какой странице он применён, приходилось определять эти PageObject через переменные, e.g.:
import pageobject.*
import pageobject.properties.*
import pageobject.search.*
import pageobject.selector.*
import pageobject.tabs.*
import static pageobject.PageObjectFactory.getPage
def authorLogin = "aaa"
def authorPassword = "bbb"
def firstApproverLogin = "ccc"
def firstApproverPassword = "ddd"
def secondApproverLogin = "eee"
def secondApproverPassword = "fff"
def firstApproverComment = "ggg"
def regNumberbudget = "kkk"
def sleepInterval = 20000
// Вход в систему под Автором
loginLogoutPage.login(authorLogin, authorPassword)
// Вызов меню Создать Договор бюджета
menuBarPage.pressFileCreateMenuItem(MenuBarPage.FileCreateMenuItem.CONTRACT)
// Заполнение обязательных полей карточки
//1. Добавление контента
contractPage.selectFile("C:\\Users\\lll\\Desktop\\Архивная справка_скан.PDF")
// Выбор бюджета
//1. Нажать кнопку выбор бюджета
contractPage.pressSelectBudget()
//2. Страница селектора бюджетов, Ввести значение в поле номер
selectorBudgetPage.inputRegNum(regNumberbudget)
//3. Нажать кнопку поиск
selectorBudgetPage.pressSearch()
//4. Добавить первый результат поиска к выбранным
selectorBudgetPage.clickFirstResult()
//5. Нажать кнопку выбрать
selectorBudgetPage.pressSelectButton()
Написано на Groovy.
Тут объекты loginLogoutPage, menuBarPage, contractPage и т.д. фактически являются PageObject и определены как часть языка (с помощью простого конфига для IDEA будут подсвечиваться в IDE с поддержкой autocomlite). Т.е. в скрипте их создавать не нужно. Из за того, что это свой DSL, со своими объектами языка, скрипт имеет своё расширение. (в конфиге для IDE как раз и прописываются правила обработки файлов этого расширения). Блок с импортами во всех скриптах одинаков и фактически является копипастой, но вынести в отдельный файл не получилось.
Работа с этим скриптов проста — сначала пишется test case, потом после каждой строчки test case пишется на DSL код. Фактически получается простое соотношение — строчка test case равна строчке на DSL. Ничего лишнего. Пример этого виден в скрипте — комментарии как раз и являются test case.
А у Вас надобности в создании своего DSL (domain specific language) для тестов не было? Что бы абстрагироваться от кода и писать в бизнес терминах? Мы так делали. Очень удобно — программисты раз написали DSL (пишется очень легко — по сути у нас нужна была поддержка pageObject на уровне языка, что бы их не создавать в коде) и дальше QA пишут тестовый скрипт, который не содержит в себе никаких лишних строк — только бизнес действия (плюс в верху для всех тестовых скриптов одинаковая «шапка» импорта).
Добрый день, Randll! Вопрос не по самой игре, а по коду. У вас встречаются аннотации NotNull. Я так понял, это аннотации IDEA, которые на этапе компиляции говорят, что тут не может быть null? Если да, то я такие штуки использовал только в академических целях. А как они на большом проекте (почти 2 миллиона строк на Java, как вы сказали)? Во всём коде пишутся эти аннотации? Не слишком ли напрягает это аннотирование и вообще стоит ли оно того?
Да, но тут бы я всё же сделал акцент на то, что если есть ТЗ, а по нему уже пишется web сервис, то лучше всё же сначала начать с wsdl. Хотя написание wsdl — не тривиальная задача. Я смотрел разные программы по редактированию xml, xsd и wsdl. Начиная от простых редакторов (e.g. Notepad++) и встроенных в IDE средств редактирования xml (IDEA & Eclipse) и заканчивая большими платными спец. программами — Oxygen XML Editor и Altova XmlSpy. Во всех них нельзя просто так взять и написать wsdl (а ля, набросать Drag'n'Drop'ом web методы) — нужно изучить wsdl и xsd прежде чем что то получится.
По моему ошибка не в самом thread local, а в известной проблеме «утечки памяти» из за не статических внутренних классов. Хотя Вы это написали :) Но я таки бы сделал упор, что это ошибка утечки памяти с внутренними классами, а как одно из проявлений — работа с ThreadLocal.
Ссылки по теме: blogs.oracle.com/olaf/entry/memory_leaks_made_easy habrahabr.ru/post/132500/
P.S. А вообще статья понравилась!
Автор выше писал: habrahabr.ru/post/219137/#comment_7491639 Хотя такую информацию неплохо было бы добавит в статью, а то сразу вопрос возникает: Что за переходник? :-)
Добрый день!
Чисто теоретический вопрос: А вместо i2c можно ли для LCD использовать сдвиговый регистр? Нам же вроде для LCD не нужно никакие данные читать, а только писать и для этого вполне подойдёт сдвиговый регистр для выхода? Я так понимаю, что в этом случае нужно будет писать какую то свою библиотеку для работы с LCD через сдвиговый регистр.
Как то обращался к вашей тех. поддержке по поводу глюков IDEA. Ответили очень быстро (около 30 минут после отправки запроса) и сразу же решили проблему. Остался очень доволен! Молодцы!
Кстати, а как у вас происходит проверка того, обратившийся пользователь имеет право не тех. поддержку или нет? Ну там, зарегистрировал ли он продукт и ещё как? Или вы все запросы на тех поддержку обрабатываете?
А где будут выкладывать видео? А то я хотел бы большую часть выступлений посетить (уж больно всё интересно :) ), но физически не получится. Вот придётся на видео смотреть. И как вы об этом сообщите, что выложено видео? Ну, т.е. как об этом можно узнать, что бы не пропустить. А слайды будут?
Добрый день!
А не могли бы вы объяснить различия между ME и SE в Raspberry Pi? Просто для неё есть обе JRE, а вот чем они различаются и какие у них преимущества по сравнению с друг другом я не знаю. Я так думаю, что для ME нужно меньше памяти, а SE зато позволят запускать любые Java-приложения. Но на этом мои знания ограничиваются.
На прошлом Java One, когда как раз активно демонстрировали возможности Raspberry Pi с Java SE и ME, этих различий не показали.
А то так для меня получается, что ME есть, но лучше использовать SE, т.к. на SE можно запускать все приложения.
А как раньше код документировался в XCode? Были какие-то стандарты? Я, собственно, почему спрашиваю — в Java есть JavaDoc, который идёт «из коробки». А тут получается ничего подобного не было?
У нас была потребность конвертировать xls в pdf. Перепробовав кучу вариантов в итоге остановились на LibreOffice и jodconverter (немного допиленный под наши нужды). Выбрали именно LibreOffice, а не OpenOffice, т.к. последний плохо работал под виндой, а у нас разработка шла под Win, а эксплуатация под Linux. Но оба имели одни и тебе проблемы — периодически падали. И не понятно почему — просто в один момент завершались и всё, без записи чего либо в лог. Потратив кучу времени ничего не нашли (может на тот момент опыта не хватило). В итоге сделали топорное но надёжное решение — скрипт периодически мониторит наличие процесса LibreOffice и если не находит, то запускает. С этим скриптом система работает уже 3 года :)
Потом, присоединяюсь к товарищу asm0dey — можно каждый раз не запускать соединение. У нас оно единожды запускалось, но, т.к. иногда LibreOffice перезагружался (см. выше), то непосредственно перед конвертацией проверялось, что соединение есть и, если нет, устанавливалось. Но тут маленькое примечание — нам не нужна была многопоточность при конвертации, поэтому конвертация была synchronize — каждый поток, которому нужно было конвертировать, ждал своей очереди. Т.ч. singletone соединения нам было достаточно.
Плюс ещё комментарий на тему jodconverter — т.к. он сейчас не поддерживается (насколько я понял), то всегда можно конвертировать самими средствами LibreOffice — примеры есть на сайте. Там ничего сложного нет, только будет немного больше кода. Т.е. jodconverter — это просто надстройка над стандартными средствами конвертации, которая упрощает типовые задачи по конвертации. И ничего более. Так что от него можно будет при надобности отказаться.
Вы написали:
Это означает, что всего констант в классе может быть не больше 65535?
Да, у нас так получилось, что большинство PageObject не нужно было каждый раз заново создавать, но в паре мест, где PageObject должен знать в контексте какой странице он применён, приходилось определять эти PageObject через переменные, e.g.:
Написано на Groovy.
Тут объекты loginLogoutPage, menuBarPage, contractPage и т.д. фактически являются PageObject и определены как часть языка (с помощью простого конфига для IDEA будут подсвечиваться в IDE с поддержкой autocomlite). Т.е. в скрипте их создавать не нужно. Из за того, что это свой DSL, со своими объектами языка, скрипт имеет своё расширение. (в конфиге для IDE как раз и прописываются правила обработки файлов этого расширения). Блок с импортами во всех скриптах одинаков и фактически является копипастой, но вынести в отдельный файл не получилось.
Работа с этим скриптов проста — сначала пишется test case, потом после каждой строчки test case пишется на DSL код. Фактически получается простое соотношение — строчка test case равна строчке на DSL. Ничего лишнего. Пример этого виден в скрипте — комментарии как раз и являются test case.
Ссылки по теме:
blogs.oracle.com/olaf/entry/memory_leaks_made_easy
habrahabr.ru/post/132500/
P.S. А вообще статья понравилась!
Чисто теоретический вопрос: А вместо i2c можно ли для LCD использовать сдвиговый регистр? Нам же вроде для LCD не нужно никакие данные читать, а только писать и для этого вполне подойдёт сдвиговый регистр для выхода? Я так понимаю, что в этом случае нужно будет писать какую то свою библиотеку для работы с LCD через сдвиговый регистр.
Кстати, а как у вас происходит проверка того, обратившийся пользователь имеет право не тех. поддержку или нет? Ну там, зарегистрировал ли он продукт и ещё как? Или вы все запросы на тех поддержку обрабатываете?
А не могли бы вы объяснить различия между ME и SE в Raspberry Pi? Просто для неё есть обе JRE, а вот чем они различаются и какие у них преимущества по сравнению с друг другом я не знаю. Я так думаю, что для ME нужно меньше памяти, а SE зато позволят запускать любые Java-приложения. Но на этом мои знания ограничиваются.
На прошлом Java One, когда как раз активно демонстрировали возможности Raspberry Pi с Java SE и ME, этих различий не показали.
А то так для меня получается, что ME есть, но лучше использовать SE, т.к. на SE можно запускать все приложения.