пятница, 12 июля 2013 г.

'cucumber --expand' and Jenkins junit reports

It seems like if you run cucumber with parameter '--expand' on Jenkins then 'Publish JUnit test result report' won't work at all.

I am absolutely sure that there is a reason why Jenkins does not show test results if '--expand' was added .

четверг, 11 июля 2013 г.

How to realize inheritance of 'class methods' of modules in Ruby



# This script shows how to call parent method in module A from the method in module B that is overwritten.
# Output of calling:

#This is D
#Calling D.b
#
#this is A.ClassMethodsA.b
#Called from:D.b
#
#this is A.ClassMethodsA.a_b
#Called from:D.a_b
#
#this is B.ClassMethodsB.b
#Called from:D.b



# if you change the order of calling 'extend' in child module
# def self.included(base)
#   base.extend(ClassMethodsA)
#   base.extend(ClassMethodsB)
# end
#
# the output will be looks like this:

#This is D
#Calling D.b
#
#this is B.ClassMethodsB.b
#Called from:D.b
#
#this is A.ClassMethodsA.b
#Called from:D.b
#
#this is A.ClassMethodsA.a_b
#Called from:D.a_b

module A
  def self.included(base)
    base.extend(A::ClassMethodsA)
  end 

  module ClassMethodsA
    def b
      puts "this is A.ClassMethodsA.b"
      puts 'Called from:' + name + '.' + __method__.to_s
      puts ''
      a_b
      super if defined?(super)
    end
    def a_b
      puts "this is A.ClassMethodsA.a_b"
      puts 'Called from:' + name + '.' + __method__.to_s
      puts ''
    end

  end
end


module B
  module ClassMethodsB
    def b
      puts "this is B.ClassMethodsB.b"
      puts 'Called from:' + name + '.' + __method__.to_s
      puts ''
      super if defined?(super)
    end
  end

  include A
  def self.included(base)
    base.extend(ClassMethodsB)
    base.extend(ClassMethodsA)
  end
end


class D
  include B
  puts 'This is D'
  puts 'Calling D.b'
  puts ''
  b
end


среда, 10 июля 2013 г.

PageObject pattern, мультиязычные сайты и дублирование кода.

(данный текст написан скорее для себя, чем для кого то, но если он окажется Вам полезным, то похлопайте в ладоши :) )

Столкнулся со следующей ситуацией.
Есть 3 сайта с очень похожим функционалом. Можно сказать что "почти" одинаковые. Работают на одной платформе, но нацеленные на разные сегменты рынка.

Похожая ситуация может быть с мультиязычными сайтами. Иногда даже дизайн для разных стран может немного отличаться.

Нужно автоматизировать некоторые регрессионные тесты.

Когда мы используем PageObject pattern, мы описываем структуру страницы, привязываясь к элементам страницы с помощью селекторов.
Но штука в том, что в моем случае для разных сайтов селекторы могут различаться.
Я использую page-object gem (Ruby) для реализации паттерна PageObject. В нем привязка выполняется на этапе создания класса, когда вызываются методы класса, создающие методы экземпляра класса, с помощью которых я могу потом взаимодействовать с элементами страницы

Таким образом мы приходим к тому, что нужно создавать 3 отдельных класса для каждой страницы. Например: SiteOneHomePage, SiteTwoHomePage, SiteThreeHomePage.
В этих классах будет (как мне кажется на данный момент) одинаковый функционал и будут различаться только селекторы.

Создавать 3 почти одинаковых класса не хочется.

Нужно найти варианты, когда не будет дублирования кода класса страницы.

Пока писал этот текст, пришел в голову вариант, когда функционал страницы описывается в модули, а потом подмешивается в класс страницы. Не знаю, как это будет выглядеть на практике, но надо попробовать.

Другой вариант, который подходит не только для Руби -- это абстрактный класс HomePage, в котором описан функционал, и классы-наследники SiteOneHomePage, SiteTwoHomePage и т.д., где описываются селекторы.

Но мне все еще это не совсем нравится.
Я использую cucumber поверх page-object для создания красивых отчетов для клиентов.
Если применить сказанное выше, то мы получим нечто следующее:

Feature: change currency (SiteOne, SiteTwo, SiteThree)
  Scenario Outline: Check currency changing on SiteOne site
    Given I open "HomeSiteOne" page on "SiteOne" site
    When I change currency to "<selected_currency>"
    Then Current currency should be "<expected_currency>"
    Examples:
      | selected_currency | expected_currency |
      | USD               | USD               |
      | EUR               | EUR               |
      | AUD               | AUD               |
      | CAD               | CAD               |

  Scenario Outline: Check currency changing on SiteTwo site
    Given I open "HomeSiteTwo" page on "SiteTwo" site
    When I change currency to "<selected_currency>"
    Then Current currency should be "<expected_currency>"
  Examples:
    | selected_currency | expected_currency |
    | USD               | USD               |
    | EUR               | EUR               |
    | AUD               | AUD               |
    | CAD               | CAD               |


Получается тавтология.
Я бы хотел, чтобы название сайта не фигурировало в названии страницы.