블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함

calendar

            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            

IT Nomad life for 17 years

2017.04.27 09:45 | Posted by 솔웅








IT Nomad life for 17 years






South Korea -> India -> Slovakia -> Netherlands -> USA



traveled five countries all over the world.



NJ (Little Ferry) -> RI (Smithfield) -> CA (San Diego) -> MN (Eden Prairie) -> IL (Chicago)



lived in 5 states in the USA.



Such a challenging life. :)





It's My Life




This ain't a song for the broken-hearted
No silent prayer for the faith-departed
I ain't gonna be just a face in the crowd
You're gonna hear my voice
When I shout it out loud

It's my life
It's now or never
I ain't gonna live forever
I just want to live while I'm alive
(It's my life)
My heart is like an open highway
Like Frankie said
I did it my way
I just want to live while I'm alive
It's my life

This is for the ones who stood their ground
It's for Tommy and Gina who never backed down
Tomorrow's getting harder, make no mistake
Luck ain't enough
You've got to make your own breaks

It's my life
And it's now or never
I ain't gonna live forever
I just want to live while I'm alive
(It's my life)
My heart is like an open highway
Like Frankie said
I did it my way
I just want to live while I'm alive
It's my life

You better stand tall when they're calling you out
Don't bend, don't break, baby, don't back down

It's my life
And it's now or never
I ain't gonna live forever
I just want to live while I'm alive
(It's my life)
My heart is like an open highway
Like Frankie said
I did it my way
I just want to live while I'm alive
(It's my life)




저작자 표시 비영리 동일 조건 변경 허락
신고




Using Hamcrest for testing - Tutorial





1. Purpose of the Hamcrest matcher framework


Hamcrest is a framework for software tests. Hamcrest allows checking for conditions in your code via existing matchers classes. It also allows you to define your custom matcher implementations.


Hamcrest는 소프트웨어 테스트를위한 framework입니다. Hamcrest는 기존 matchers 클래스를 통해 코드의 조건을 확인할 수 있습니다. 또한 사용자 정의 matcher implementations 을 정의 할 수 있습니다.


To use Hamcrest matchers in JUnit you use the assertThat statement followed by one or several matchers.


JUnit에서 Hamcrest matcher를 사용하려면 assertThat 문 뒤에 하나 또는 여러 개의 matchers를 사용합니다.


Hamcrest is typically viewed as a third generation matcher framework. The first generation used assert(logical statement) but such tests were not easily readable. The second generation introduced special methods for assertions, e.g., assertEquals(). This approach leads to lots of assert methods. Hamcrest uses assertThat method with a matcher expression to determine if the test was succesful. See Wiki on Hamcrest for more details.


Hamcrest는 일반적으로 3 세대 정규식 framework로 간주됩니다. 1 세대는 assert(logical statement)을 사용했지만 그러한 테스트는 쉽게 읽을 수 없었습니다. 2 세대에서는 assertEquals()와 같은 assertions을 위한 특수한 메소드가 도입되었습니다. 이 접근법은 많은 assert methods 를 필요로 합니다. Hamcrest는 assertThat 메서드를 사용하여 테스트가 성공적인지 여부를 확인하는 matcher expression을 사용합니다. 자세한 내용은 Hamcrest의 Wiki를 참조하십시오.




Hamcrest has the target to make tests as readable as possible. For example, the is method is a thin wrapper for equalTo(value).


Hamcrest는 최대한 가독성있는 test scripts를 가지는 것을 목표로 하고 있습니다. 예를 들어, is 메소드는 equalTo(value)에 대한 thin wrapper입니다.


import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.equalTo;

boolean a;
boolean b;

// all statements test the same
assertThat(a, equalTo(b));
assertThat(a, is(equalTo(b)));
assertThat(a, is(b));


The following snippets compare pure JUnit 4 assert statements with Hamcrest matchers.


다음 snippets은 순수 JUnit 4 assert statements와 Hamcrest matchers를 비교합니다.


// JUnit 4 for equals check
assertEquals(expected, actual);
// Hamcrest for equals check
assertThat(actual, is(equalTo(expected)));

// JUnit 4 for not equals check
assertNotEquals(expected, actual)
// Hamcrest for not equals check
assertThat(actual, is(not(equalTo(expected))));

It is also possible to chain matchers, via the anyOf of allOf method.


allOf 메소드의 anyOf를 통해 matcher를 연결할 수도 있습니다.


assertThat("test", anyOf(is("testing"), containsString("est")));

In general the Hamcrest error messages are also much easier to read.


일반적으로 Hamcrest 오류 메시지는 읽기가 훨씬 쉽습니다.


assertTrue(result instanceof String);
// error message:
java.lang.AssertionError
    at org.junit.Assert.fail(Assert.java:86)
    at org.junit.Assert.assertTrue(Assert.java:41)
    at org.junit.Assert.assertTrue(Assert.java:52)
// ...


assertEquals(String.class, result.getClass());
// error message:
java.lang.NullPointerException
    at com.vogella.hamcrest.HamcrestTest.test(HamcrestTest.java:30)
// ....


assertThat(result, instanceOf(String.class));
// error message:
java.lang.AssertionError:
Expected: an instance of java.lang.String
     but: null
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
// ...


Using Hamcrest matchers also provides more type safety as these matchers use generics.


Hamcrest matchers를 사용하면 matcher가 generics를 사용하므로 더 많은 type safety을 제공합니다.





2. Using Hamcrest matchers


2.1. Defining a Hamcrest dependency for Gradle


To use Hamcrest matchers for a project based on the Gradle build system, add the following dependencies to it.

Gradle 빌드 시스템을 기반으로하는 프로젝트에 Hamcrest matchers를 사용하려면 다음 dependencies를 추가하십시오.


dependencies {
    // Unit testing dependencies
    testCompile 'junit:junit:4.12'
    // Set this dependency if you want to use Hamcrest matching
    testCompile 'org.hamcrest:hamcrest-library:1.3'
}


2.2. Defining a Hamcrest dependency for Maven


To use the library for a Maven based project, the following dependency to your pom file.


Maven 기반 프로젝트에 라이브러리를 사용하려면, pom 파일에 다음과 같은 dependencies를 부여하십시오.


<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>



2.3. Adding Hamcrest directly to the classpath in Eclipse



The JUnit distribution included in Eclipse only contain the core Hamcrest matcher. To use all available matchers, download the latest hamcrest-all-*.jar from https://code.google.com/p/hamcrest/downloads/list and add it to your projects classpath.


Eclipse에 포함 된 JUnit 배포판에는 core Hamcrest matcher 만 포함됩니다. 사용 가능한 모든 matcher를 사용하려면 https://code.google.com/p/hamcrest/downloads/list에서 최신 hamcrest-all - * .jar 파일을 다운로드하여 프로젝트 classpath에 추가하십시오.


If you get the following exception "java.lang.SecurityException: class "org.hamcrest.Matchers"'s signer information does not match signer information of other classes in the same package", ensure that the hamcrest jar is before the Junit library in the build path. You an configure the order in the project properties in the Eclipse IDE under Java Build Path on the Order and Export tab.


"java.lang.SecurityException : class"org.hamcrest.Matchers "의 서명자 정보가 같은 패키지의 다른 클래스의 서명자 정보와 일치하지 않는 경우"hamcrest jar가 Junit 라이브러리보다 앞에 있는지 확인하십시오. 빌드 경로. Eclipse IDE의 프로젝트 특성에서 순서 및 내보내기 탭의 Java 빌드 경로 아래에 순서를 구성하십시오.







3. Using Hamcrest


3.1. Example


The usage of Hamcrest matchers is demonstrates by the following code snippet.


Hamcrest matchers의 사용법은 다음 code snippet을 통해 보여줍니다.


assertThat(Long.valueOf(1), instanceOf(Integer.class));
// shortcut for instanceOf
assertThat(Long.valueOf(1), isA(Integer.class));


3.2. Static import


To make all matchers available in your file add an static import. This also makes it easier to find matchers through code completion.


파일에서 모든 matcher를 사용할 수 있게 하려면 static import를 추가하십시오. 이러면 code completion을 통해 matcher를 쉽게 찾을 수 있도록 해 주기도 합니다.


import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;



3.3. Hamcrest matchers for lists


The usage of the Hamcrest matchers for lists are demonstrated by the following example.


lists에 대한 Hamcrest matchers의 사용법은 다음 예제에서 보여 줍니다.


import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.hamcrest.core.Every.everyItem;

public class HamcrestListMatcherExamples {
    @Test
    public void listShouldInitiallyBeEmpty() {
        List<Integer> list = Arrays.asList(5, 2, 4);

        assertThat(list, hasSize(3));

        // ensure the order is correct
        assertThat(list, contains(5, 2, 4));

        assertThat(list, containsInAnyOrder(2, 4, 5));

        assertThat(list, everyItem(greaterThan(1)));

    }
}
// Check that a list of objects has a property race and
// that the value is not ORC
assertThat(fellowship, everyItem(hasProperty("race", is(not((ORC))))));



3.4. Overview of Hamcrest mather



The following are the most important Hamcrest matchers:


다음은 가장 중요한 Hamcrest matchers들 입니다.


  • allOf - matches if all matchers match (short circuits)

  • anyOf - matches if any matchers match (short circuits)

  • not - matches if the wrapped matcher doesn’t match and vice

  • equalTo - test object equality using the equals method

  • is - decorator for equalTo to improve readability

  • hasToString - test Object.toString

  • instanceOfisCompatibleType - test type

  • notNullValuenullValue - test for null

  • sameInstance - test object identity

  • hasEntryhasKeyhasValue - test a map contains an entry, key or value

  • hasItemhasItems - test a collection contains elements

  • hasItemInArray - test an array contains an element

  • closeTo - test floating point values are close to a given value

  • greaterThangreaterThanOrEqualTolessThanlessThanOrEqualTo

  • equalToIgnoringCase - test string equality ignoring case

  • equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace

  • containsStringendsWithstartsWith - test string matching


To see all matchers, use API reference.


모든 matchers를 보려면 API 참조를 사용하십시오.


4. Exercise - Writing a custom Hamcrest matcher using FeatureMatcher


4.1. Target



The target of this exercise is to write a custom matcher with Hamcrest.


이 exercise의 목표는 Hamcrest 에서 custom matcher를 작성하는 것입니다.



4.2. Create Hamcrest Matchers


Define a custom matcher for Hamcrest which provides the length matcher for a String. We want to use the class FeatureMatcher. With FeatureMatcher we can wrap an existing Matcher, decide which field of the given Object under test to match and provide a nice error message. The constructor of FeatureMatcher takes the following arguments in this order:


Hamcrest를위한 custom matcher를 정의하여 String에 대한 length matcher를 제공합니다. 우리는 FeatureMatcher 클래스를 사용하고자합니다. FeatureMatcher를 사용하면 기존 Matcher를 wrap하고 테스트 할 대상 객체의 필드를 결정하여 나은 오류 메시지를 제공 할 수 있습니다. FeatureMatcher의 생성자는 다음 순서로 인수를 취합니다.



  • The matcher we want to wrap

  • a description of the feature that we tested

  • a description of the possible mismatch


The only method we have to overwrite is featureValueOf(T actual) which returns the value which will get passed into the wrapped matches()/matchesSafely() method.


overwrite하는 유일한 방법은 wrapped matches () / matchesSafely () 메서드에 전달 될 값을 반환하는 featureValueOf (T actual)입니다.


public static Matcher<String> length(Matcher<? super Integer> matcher) {
    return new FeatureMatcher<String, Integer>(matcher, "a String of length that", "length") {
        @Override
        protected Integer featureValueOf(String actual) {
            return actual.length();
        }
    };
}


4.3. Validate



Use your custom matcher to check that "Gandalf" has a lenght of 8.


Gandalf의 길이가 8인지에 대해 여러분의 custom matcher 를 사용해서 확인해 보세요.


@Test
public void fellowShipOfTheRingShouldContainer7() {
        assertThat("Gandalf", length(is(8)));
}
public static  Matcher<String> length(Matcher<? super Integer> matcher) {
        return new FeatureMatcher<String, Integer>(matcher, "a String of length that", "length") {
                @Override
                protected Integer featureValueOf(String actual) {
                  return actual.length();
                }
        };
}



5. Exercise: Writing your custom Hamcrest matcher using TypeSafeMatcher



It is possible to write your custom Hamcrest matcher by extending TypeSafeMatcher. In contrast to BaseMatcher the TypeSafeMatcher class automatically checks for null values, checks the type and casts appropriately before delegating to matchesSafely(). It provides type safety by default. The following is an example for defining a matcher which allows testing if a String matches a regular expression.


TypeSafeMatcher를 extends하여 custom Hamcrest matcher를 작성할 수 있습니다. BaseMatcher와 달리 TypeSafeMatcher 클래스는 자동으로 null 값을 확인하고, types를 검사하고 matchesSafely ()에 위임하기 전에 적절하게 형 변환합니다. 기본적으로 type safety 을 제공합니다. 다음은 문자열이 정규 표현식 regular expression 과 일치하는지 테스트 할 수있는 matcher를 정의하는 예제입니다.


import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;

public class RegexMatcher extends TypeSafeMatcher<String> {

        private final String regex;

        public RegexMatcher(final String regex) {
                this.regex = regex;
        }

        @Override
        public void describeTo(final Description description) {
                description.appendText("matches regular expression=`" + regex + "`");
        }

        @Override
        public boolean matchesSafely(final String string) {
                return string.matches(regex);
        }


         // matcher method you can call on this matcher class
    public static RegexMatcher matchesRegex(final String regex) {
        return new RegexMatcher(regex);
    }
}


The following snippet gives an example how to use it.


다음 snippet에는 이를 사용하는 예가 나와 있습니다.


package com.vogella.android.testing.applicationtest;


import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;

public class TestCustomMatcher {

    @Test
    public void testRegularExpressionMatcher() throws Exception {
        String s ="aaabbbaaaa";
        assertThat(s, RegexMatcher.matchesRegex("a*b*a*"));
    }

}


6. Exercise: Combining matchers


Combining matchers is supported by Hamcrest out of the box but it has the limitation that the error is hard to read:


matchers를 결합하는 것은 Hamcrest에 오류가 읽기 어렵다는 제한이 있습니다.

@Test
public void () {
    List<Integer> list = new ArrayList<>();
    assertThat(list, both(hasSize(1)).and(contains(42)));
}
Expected: (a collection with size <1> and iterable containing [<42>])
     but: a collection with size <1> collection size was <0>.


This not very readable.


이렇게 가독성이 떨어집니다.



6.1. Target



We want to write our own MatcherCombiner that provides us with a readable error message, even when multiple matchers fail.


우리는 multiple matchers가 fail하더라도 가독성있는 에러 메시지를 제공하는 MatcherCombiner를 별도로 작성하려고합니다.



6.2. Create MatchCombiner



We do this by inheriting from BaseMatch and by providing a starting method that let’s us chain matchers together. The matchers get saved in a list that we iterate over during the matching phase.


우리는 BaseMatch로부터 상속하고 chain matcher를 함께 묶어주는 것을 시작하면서 이 작업을 수행합니다. matchers는 matching phase 동안에 반복되는 list 저장됩니다.


public class MatcherCombinator<T> extends BaseMatcher<T> {
    private final List<Matcher<? super T>> matchers = new ArrayList<>();
    private final List<Matcher<? super T>> failedMatchers = new ArrayList<>();

    private MatcherCombinator(final Matcher<? super T> matcher) {
        matchers.add(matcher);
    }

    public MatcherCombinator<T> and(final Matcher<? super T> matcher) {
        matchers.add(matcher);
        return this;
    }

    @Override
    public boolean matches(final Object item) {
        boolean matchesAllMatchers = true;
        for (final Matcher<? super T> matcher : matchers) {
            if (!matcher.matches(item)) {
                failedMatchers.add(matcher);
                matchesAllMatchers = false;
            }
        }
        return matchesAllMatchers;
    }

    @Override
    public void describeTo(final Description description) {
        description.appendValueList("\n", " " + "and" + "\n", "", matchers);
    }

    @Override
    public void describeMismatch(final Object item, final Description description) {
        description.appendText("\n");
        for (Iterator<Matcher<? super T>> iterator = failedMatchers.iterator(); iterator.hasNext();) {
            final Matcher<? super T> matcher = iterator.next();
            description.appendText("Expected: <");
            description.appendDescriptionOf(matcher).appendText(" but ");
            matcher.describeMismatch(item, description);
            if (iterator.hasNext()) {
                description.appendText(">\n");
            }
        }
    }

    public static <LHS> MatcherCombinator<LHS> matches(final Matcher<? super LHS> matcher) {
        return new MatcherCombinator<LHS>(matcher);
    }
}


To validate the implementation we write a new test.


implementation을 validate하기 위해 새로운 테스트를 작성합니다.


@Test
public void test() {
    List<Integer> list = new ArrayList<>();
    assertThat(list, matches(hasSize(1)).and(contains(42)));
}
java.lang.AssertionError:
Expected:
<a collection with size <1>> and
<iterable containing [<42>]>
     but:
Expected: <a collection with size <1> but collection size was <0>>
Expected: <iterable containing [<42>] but No item matched: <42>.


You can adjust this output in the describeMismatch method.


describeMismatch method 에서 이 output을 adjust 할 수 있습니다.



7. Grouping your matchers for import



If you define many custom matchers it might become tedious to import them one by one into your test files. By grouping them into a single class you can import them with one statement. You can also group them together with Hamcrest matchers.


많은 custom matchers를 정의하면 테스트 파일에 하나씩 import하는 것이 불편 할 수 있습니다. single class로 그룹화하여 하나의 statement로 가져올 수 있습니다. Hamcrest matchers와 함께 그룹화 할 수도 있습니다.



package com.vogella.hamcrest;
import com.vogella.hamcrest.matchers.RegexMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;

public class MyMatchers
{
    public static <T> Matcher<T> instanceOf(Class<T> target) {
        return Matchers.instanceOf(target);
    }

   public static Matcher<String> matchesRegex(String target) {
          return RegexMatcher.matchesRegex(target);
   }
}


In your test file:

import static com.vogella.hamcrest.MyMatchers.*;


















저작자 표시 비영리 동일 조건 변경 허락
신고


Cucumber Introduction:


Cucumber is a tool based on Behavior Driven Development (BDD) framework which is used to write acceptance tests for web application. It allows automation of functional validation in easily readable and understandable format (like plain English) to Business Analysts, Developers, Testers, etc.


Cucumber는 BDD (Behavior Driven Development) 프레임 워크를 기반으로 웹 응용 프로그램에 대한 acceptance 테스트를 작성하는 데 사용되는 도구입니다. 비즈니스 분석가, 개발자, 테스터 등이 쉽게 읽을 수 있고 이해할 수있는 형식 (일반 영어와 같은)으로 기능 검증을 자동화 할 수 있습니다.


Cucumber feature files can serve as a good document for all. There are many other tools like JBehave which also support BDD framework. Initially Cucumber was implemented in Ruby and then extended to Java framework. Both the tools support native JUnit.


Cucumber feature 파일은 훌륭한 문서 역할을 할 수 있습니다. BDD 프레임 워크를 지원하는 툴 들 로는 JBehave 등과 같은 다른 많은 도구들도 있습니다. 처음에 Cucumber는 Ruby에서 구현되었고 Java 프레임 워크로 확장되었습니다. 두 도구 모두 native JUnit을 지원합니다.


Behavior Driven Development is extension of Test Driven Development and it is used to test the system rather than testing the particular piece of code. We will discuss more about the BDD and style of writing BDD tests.


Behavior Driven Development는 Test Driven Development의 확장이며 특정 코드를 테스트하는 대신 시스템을 테스트하는 데 사용됩니다. 아래에 BDD 및 BDD 테스트 작성 스타일에 대해 자세히 설명합니다.


Cucumber can be used along with Selenium, Watir, and Capybara etc. Cucumber supports many other languages like Perl, PHP, Python, .Net etc. In this tutorial we will concentrate on Cucumber with Java as a language.


Cucumber는 Selenium, Watir, Capybara 등과 함께 사용할 수 있습니다. Cucumber는 Perl, PHP, Python, .NET 등의 많은 다른 언어를 지원합니다.이 튜토리얼에서는 Java와 함께 Cucumber를 언어로 사용합니다.




Cucumber Basics:


In order to understand cucumber we need to know all the features of cucumber and its usage.


Cucumber를 이해하기 위해서는 Cucumber의 모든 특징과 사용법을 알아야합니다.


#1) Feature Files:


Feature files are essential part of cucumber which is used to write test automation steps or acceptance tests. This can be used as live document. The steps are the application specification. All the feature files ends with .feature extension.


Feature file은 테스트 자동화 단계 또는 acceptance 테스트를 작성하는 데 사용되는 Cucumber의 핵심 부분입니다. 이것은 live document로 사용할 수 있습니다. steps는 application specification입니다. 모든 Feature file은 .feature 확장자로 끝납니다.



Sample feature file:

Feature: Login Functionality Feature

In order to ensure Login Functionality works,
I want to run the cucumber test to verify it is working

Scenario: Login Functionality

Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as “USER” and Password “PASSWORD”
Then login should be successful

Scenario: Login Functionality

Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as “USER1” and Password “PASSWORD1”
Then error message should be thrown


#2) Feature:


This gives information about the high level business functionality (Refer to previous example) and the purpose of Application under test. Everybody should be able to understand the intent of feature file by reading the first Feature step. This part is basically kept brief.


여기에는 대략적인 개념의 business functionality (이전 예 참조) 및 테스트중 인 응용 프로그램의 목적에 대한 정보가 있습니다. 첫 번째 Feature step을 읽으면 누구나 이 Feature file의 의도를 이해할 수 있어야 합니다. 이 부분은 기본적으로 간략하게 작성합니다.


#3) Scenario:

Basically a scenario represents a particular functionality which is under test. By seeing the scenario user should be able to understand the intent behind the scenario and what the test is all about. Each scenario should follow given, when and then format. This language is called as “gherkin”.


기본적으로 시나리오는 테스트중인 특정 기능을 나타냅니다. 시나리오 사용자는 시나리오의 의도와 그 테스트가 무엇인지 이해할 수 있어야합니다. 각 시나리오는 주어진 시간과 형식을 따라야합니다. 이 언어는 "작은 Cucumber (gherkin)"라고 불립니다.


  1. Given: As mentioned above, given specifies the pre-conditions. It is basically a known state.
  2. When: This is used when some action is to be performed. As in above example we have seen when the user tries to log in using username and password, it becomes an action.
  3. Then: The expected outcome or result should be placed here. For Instance: verify the login is successful, successful page navigation.
  4. Background: Whenever any step is required to perform in each scenario then those steps needs to be placed in Background. For Instance: If user needs to clear database before each scenario then those steps can be put in background.
  5. And: And is used to combine two or more same type of action.

Example:

Feature: Login Functionality Feature

Scenario: Login Functionality
Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as “USER”
And password as “password”
Then login should be successful
And Home page should be displayed

Example of Background:

Background:

Given user logged in as databases administrator
And all the junk values are cleared


#4) Scenario Outline:

Scenario outlines are used when same test has to be performed with different data set. Let’s take the same example. We have to test login functionality with multiple different set of username and password.

시나리오 개요는 동일한 테스트가 여러 다른 data set로 수행되어야 할 때 사용됩니다. 같은 예를 들어 봅시다. 여러 다른 사용자 이름 및 비밀번호 세트로 로그인 기능을 테스트해야합니다.


Feature: Login Functionality Feature

In order to ensure Login Functionality works,
I want to run the cucumber test to verify it is working

Scenario Outline: Login Functionality

Given user navigates to SOFTWARETESTINGHELP.COM
When user logs in using Username as <username> and Password <password>
Then login should be successful

Examples:
|username         |password          |
|Tom                     |password1        |
|Harry                   |password2        |
|Jerry                    |password3        |

Note:

  1. As shown in above example column names are passed as parameter to When statement.
  2. In place of Scenario, you have to use Scenario Outline.
  3. Examples are used to pass different arguments in tabular format. Vertical pipes are used to separate two different columns. Example can contain many different columns.

     
    위의 예에서와 같이 열 이름은 매개 변수로 When 문에 전달됩니다.
    Scenario 대신 Scenario Outline을 사용해야합니다.
    이 예제는 다른 인수를 표 형식으로 전달하는 데 사용됩니다. Vertical pipes는 두 개의 서로 다른 columns을 분리하는 데 사용됩니다. 이 예제에 많은 다른 열을 포함 할  수 있습니다.




#5) Tags:

Cucumber by default runs all scenarios in all the feature files. In real time projects there could be hundreds of feature file which are not required to run at all times.


기본적으로 Cucumber는 모든 Feature file에서 모든 시나리오를 실행합니다. 실시간 프로젝트에는 항상 실행될 필요가 없는 수백 개의 Feature file이있을 수 있습니다.


For instance: Feature files related to smoke test need not run all the time. So if you mention a tag as smokeTest in each feature file which is related to smoke test and run cucumber test with @SmokeTest tag . Cucumber will run only those feature files specific to given tags. Please follow the below example. You can specify multiple tags in one feature file.


예 : smoke test와 관련된 Feature file은 항상 실행될 필요는 없습니다. 따라서 smoke test와 관련된 각 Feature file에서 smokeTest로 태그를 언급하고 @SmokeTest 태그로 Cucumber 테스트를 실행하면됩니다. Cucumber는 특정 태그에 해당하는 Feature file 만 실행합니다. 아래의 예를 따르십시오. 하나의 Feature file에 여러 개의 태그를 지정할 수 있습니다.


Example of use of single tags:


@SmokeTest

Feature: Login Functionality Feature

In order to ensure Login Functionality works,
I want to run the cucumber test to verify it is working

Scenario Outline: Login Functionality

Given user navigates to SOFTWARETESTINGHELP.COM
When user logs in using Username as <username> and Password <password>
Then login should be successful

Examples:
|username         |password          |
|Tom     |password1        |
|Harry   |password2        |
|Jerry    |password3        |

Example of use of multiple tags:


As shown in below example same feature file can be used for smoke test scenarios as well as for login test scenario. When you intend to run your script for smoke test then use @SmokeTest. Similarly when you want your script to run for Login test use @LoginTest tag.

아래 예제에서와 같이 로그인 테스트 시나리오는 물론 Smoke Test 시나리오에도 동일한 Feature file을 사용할 수 있습니다. Smoke Test를 위해 스크립트를 실행하려면 @SmokeTest를 사용하십시오. 마찬가지로 로그인 테스트를 위해 스크립트를 실행하려면 @LoginTest 태그를 사용하십시오.


Any number of tags can be mentioned for a feature file as well as for scenario.


Feature file뿐만 아니라 시나리오에 대해서도 임의의 수의 태그를 사용 할 수 있습니다.


@SmokeTest @LoginTest


Feature: Login Functionality Feature

In order to ensure Login Functionality works,
I want to run the cucumber test to verify it is working

Scenario Outline: Login Functionality

Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as <username> and Password <password>
Then login should be successful

Examples:
|username         |password          |
|Tom     |password1        |
|Harry   |password2        |
|Jerry    |password3        |


Similarly you can specify tags to run specific scenario in a feature file. Please check below example to run specific scenario.


마찬가지로 태그를 지정하여 Feature file에서 특정 시나리오를 실행할 수 있습니다. 특정 시나리오를 실행하려면 아래 예제를 확인하십시오.


Feature: Login Functionality Feature

In order to ensure Login Functionality works,
I want to run the cucumber test to verify it is working

@positiveScenario
Scenario: Login Functionality

Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as “USER” and Password “PASSWORD”
Then login should be successful

@negaviveScenario
Scenario: Login Functionality

Given user navigates to SOFTWARETETINGHELP.COM
When user logs in using Username as “USER1” and Password “PASSWORD1”
Then error message should throw



#6) Junit Runner:


To run the specific feature file cucumber uses standard Junit Runner and specify tags in @Cucumber. Options. Multiple tags can be given by using comma separate. Here you can specify the path of the report and type of report you want to generate.


특정 Feature file을 실행하려면 cucumber가 표준 Junit Runner를 사용하고 @Cucumber에 태그를 지정하십시오. 옵션. 쉼표로 구분하여 여러 태그를 지정할 수 있습니다. 여기에서 생성하려는 보고서의 경로와 유형을 지정할 수 있습니다.


Example of Junit Runner:

1import cucumber.api.junit.Cucumber;</pre>
2import org.junit.runner.RunWith;
3@RunWith(Cucumber.class)
4@Cucumber.Options(format={"SimpleHtmlReport:report/smokeTest.html"},tags={"@smokeTest"})
5Public class JUnitRunner {
6}


Similarly you can give instruction to cucumber to run multiple tags. Below example illustrates how to use multiple tags in cucumber to run different scenarios.


마찬가지로 여러 개의 태그를 실행하기 위해 Cucumber에게 지시를 내릴 수 있습니다. 아래 예제는 Cucumber에서 여러 개의 태그를 사용하여 다른 시나리오를 실행하는 방법을 보여줍니다.


1import cucumber.api.junit.Cucumber;
2 import org.junit.runner.RunWith;
3 @RunWith(Cucumber.class)
4 @Cucumber.Options(format={"SimpleHtmlReport:report/smokeTest.html"},tags={"@smokeTest",”@LoginTest”})
5 Public class JUnitRunner {
6}



#7) Cucumber Report:


Cucumber generates its own html format. However better reporting can be done using Jenkins or bamboo tool. Details of reporting are covered in next topic of cucumber.


Cucumber는 자체적으로 HTML 형식을 생성합니다. Jenkins 또는 bamboo 도구를 사용하여 더 나은 보고를 수행 할 수 있습니다. 보고의 세부 사항은 Cucumber의 다음 주제에서 다룹니다.


Cucumber Project Setup:


Detail explanation of cucumber project set up is available separately in next tutorial. Please refer to Cucumber Tutorial Part2 from more information about project setup. Remember there is no extra software installations required for cucumber.


Cucumber 프로젝트 설정에 대한 자세한 설명은 다음 자습서에서 별도로 설명됩니다. 프로젝트 설정에 대한 자세한 내용은 Cucumber Tutorial Part2를 참조하십시오. Cucumber에 필요한 추가 소프트웨어 설치가 없음을 기억하십시오.


Implementation of Feature file:

We have to implement these steps in Java in order to test the feature files. Need to create a class which contains those given, when and then statements. Cucumber uses its annotations and all the steps are embedded in those annotations (given, when, then).Each phrase starts with “^” so that cucumber understands the start of the step. Similarly each step ends with “$”. User can use regular expressions to pass different test data. Regular expressions take data from feature steps and passes to step definitions. The order of parameters depends how they are passed from feature file. Please refer next tutorial for project setup and mapping between feature files and java classes.


Feature file을 테스트하려면 Java에서 이러한 steps를 구현해야합니다. 주어진, when 및 then 문을 포함하는 클래스를 작성해야합니다. Cucumber는 annotations을 사용하고 모든 step들은 annotations에 포함되어 있습니다 (given, when, then). 각 phrase는 "^"로 시작하여 Cucumber가 단계의 시작을 이해할 수 있도록합니다. 마찬가지로 각 단계는 "$"로 끝납니다. 사용자는 regular expressions을 사용하여 다른 테스트 데이터를 전달할 수 있습니다. 정규식 regular expressions은 feature steps에서 데이터를 가져 와서 step definitions로 전달합니다. 매개 변수 parameters 순서는 feature file에서 전달되는 방법에 따라 다릅니다. 피쳐 파일과 자바 클래스 간의 프로젝트 설정과 매핑에 대해서는 다음 튜토리얼을 참조하십시오.


Example:


Below example is to illustrate how feature files can be implemented.


아래 예제는 Feature file을 구현하는 방법을 보여줍니다.


In this example we have not used any selenium API. This is to just show how cucumber works as standalone framework. Please follow next tutorial for selenium integration with cucumber.


이 예제에서는 selenium API를 사용하지 않았습니다. Cucumber가 독립 프레임 워크로 어떻게 작동하는지 보여주기위한 것입니다. selenium과 Cucumber의 통합에 대한 내용은 next tutorial을 참조하세요.


1public class LoginTest {
2@Given("^user navigates to SOFTWARETETINGHELP.COM$")
3public void navigatePage() {
4system.out.println(“Cucumber executed Given statement”);
5}
6@When("^user logs in using Username as \"(.*)\" and Password \"(.*)\"$")
7public void login(String usename,String password) {
8system.out.println(“Username is:”+ usename);
9system.out.println(“Password is:”+ password);
10}
11@When("^click the Submit button$")
12public void clickTheSubmitButton() {
13system.out.println(“Executing When statement”)
14}
15@Then("^Home page should be displayed$")
16public void validatePage() {
17system.out.println(“Executing Then statement”)
18}
19@Then("^login should be successful$")
20public void validateLoginSuccess() {
21system.out.println(“Executing 2<sup>nd</sup> Then statement”)
22}
23}


When you execute cucumber runner class, cucumber will start reading feature file steps. For example, when you execute @smokeTest, cucumber will read Feature step and Given statement of scenario. As soon as cucumber finds Given statement, same Given statement will be searched in your java files. If same step is found in java file then cucumber executes the function specified for the same step otherwise cucumber will skip the step.


Cucumber runner class를 실행하면 Cucumber가 feature file steps를 읽습니다. 예를 들어 @smokeTest를 실행하면 cucumber는 Feature step과 Given of scenario 문을 읽습니다. Cucumber가 Given 문을 찾자마자 java 파일에서 동일한 Given 문이 검색됩니다. java 파일에서 동일한 단계가 발견되면 cucumber는 동일한 단계에 대해 지정된 함수를 실행하고 그렇지 않은 경우 그 step을 건너 뜁니다.


Conclusion:


In this tutorial, we have covered features of cucumber tool and its usage in real time scenario.
Cucumber is a most favorite tool for many projects as it is easy to understand, readable and contains business functionality.


이 튜토리얼에서는 Cucumber 도구의 기능과 그 사용법을 real time scenario 로 다루었습니다.


Cucumber는 이해하기 쉽고 읽기 쉽고 비즈니스 기능을 포함하고있어 많은 프로젝트에서 가장 많이 사용되는 도구입니다.


In the next chapter we will cover how to setup a cucumber – java project and how to integrate Selenium WebDriver with Cucumber.


다음 장에서는 Cucumber 자바 프로젝트를 설정하는 방법과 Selenium WebDriver를 Cucumber와 통합하는 방법에 대해 설명합니다.


저작자 표시 비영리 동일 조건 변경 허락
신고


Javascript sort()



var arr = ["Banana", "Orange", "Apple", "Mango", "apple", "1apple"];

arr.sort();

["1apple", "Apple", "Banana", "Mango", "Orange", "apple"]


It is case sensitive.


To make it case insensitive


var arr = ["Banana", "Orange", "Apple", "Mango", "apple", "1apple"];

arr.sort(function(a,b) {

    a = a.toLowerCase();

    b = b.toLowerCase();

    if( a == b) return 0;

    return a < b ? -1 : 1;

});

["1apple", "Apple", "apple", "Banana", "Mango", "Orange"]


or


var arr = ["Banana", "Orange", "Apple", "Mango", "apple", "1apple"];

arr.sort(

    function(a, b){

        if (a.toLowerCase() < b.toLowerCase()) return -1;

        if (a.toLowerCase() > b.toLowerCase()) return 1;

        return 0;

    }

); 

["1apple", "Apple", "apple", "Banana", "Mango", "Orange"]



Protractor


Check not exist


expect(element(by.css('.switch')).isPresent()).to.become(false).and.notify(next);

expect(items.length).toBe(0);




element.all(locator).map(mapFunction)


<ul class="items">
  <li class="one">First</li>
  <li class="two">Second</li>
  <li class="three">Third</li>
</ul>
let items = element.all(by.css('.items li')).map(function(elm, index) {
  return {
    index: index,
    text: elm.getText(),
    class: elm.getAttribute('class')
  };
});
expect(items).toEqual([
  {index: 0, text: 'First', class: 'one'},
  {index: 1, text: 'Second', class: 'two'},
  {index: 2, text: 'Third', class: 'three'}
]);

// Or using the shortcut $$() notation instead of element.all(by.css()):

let items = $$('.items li').map(function(elm, index) {
  return {
    index: index,
    text: elm.getText(),
    class: elm.getAttribute('class')
  };
});
expect(items).toEqual([
  {index: 0, text: 'First', class: 'one'},
  {index: 1, text: 'Second', class: 'two'},
  {index: 2, text: 'Third', class: 'three'}
]);


Example


step.Then(/^Verify Search Result search by "([^"]*)"$/, 
(searchName:string, done:Callback)=>{
    let cName = customerViewPage.customerNameList();

cName.map(function(eachName){
return eachName.getText().then(function(cNameList){
return cNameList;
});
}).then(function(cNameList){
for(let i = 0; i < cNameList.length; i++){
console.log(cNameList[i] + ' contains ' + searchName);
expect(cNameList[i]).is.contains(searchName);
}
done();
});
});


element.all(locator).each(eachFunction)

<ul class="items">
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</ul>
element.all(by.css('.items li')).each(function(element, index) {
  // Will print 0 First, 1 Second, 2 Third.
  element.getText().then(function (text) {
    console.log(index, text);
  });
});

// Or using the shortcut $$() notation instead of element.all(by.css()):

$$('.items li').each(function(element, index) {
  // Will print 0 First, 1 Second, 2 Third.
  element.getText().then(function (text) {
    console.log(index, text);
  });
});


Example


step.Then(/^Check sorting$/, (done: Callback)=> {
let sorted = [] , unSorted = [];
let cName = customerViewPage.customerNameList();
let i = 0;
cName.each(function(eachName){
eachName.getText().then(function(name){
// unSorted[i] = name.toLowerCase();
unSorted[i] = name;
i++;
});
}).then(function(){
sorted = unSorted.slice();
// sorted.sort();
sorted.sort(function(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
if ( a === b) {return 0;}
return a < b ? -1 : 1;
});

for(let i = 0; i < sorted.length; i++){
console.log(' Array1 : ' + sorted[i] +

' is equals to Array2 : ' + unSorted[i]);
expect(sorted[i]).is.equal(unSorted[i]);
}
done();
});
});


element.all(locator).then(thenFunction)


ElementArrayFinder.prototype.then


Retrieve the elements represented by the ElementArrayFinder. The input function is passed to the resulting promise, which resolves to an array of ElementFinders.


<ul class="items">
  <li>First</li>
  <li>Second</li>
  <li>Third</li>
</ul>


element.all(by.css('.items li')).then(function(arr) {
  expect(arr.length).toEqual(3);
});

// Or using the shortcut $$() notation instead of element.all(by.css()):

$$('.items li').then(function(arr) {
  expect(arr.length).toEqual(3);
});


저작자 표시 비영리 동일 조건 변경 허락
신고



Leaving a memo

customerNameList() {return element.all(by.css("#items")).

all(by.css(".list-item-title"));}

This customerNameList() fetches customer name list data.

step.Then(/^Check sorting$/, (done: Callback)=> {
let sorted = [] , unSorted = [];
let cName = customerViewPage.customerNameList();

cName.map(function(eachName){
return eachName.getText().then(function(unSorted){
return unSorted;
});
}).then(function(unSorted){
let sorted = unSorted.slice();
sorted = sorted.sort(); //sort the array
for(let i = 0; i < sorted.length; i++){
console.log(' Array1 : ' + sorted[i] +

' is equals to Array2 : ' + unSorted[i]);
expect(sorted[i]).is.equal(unSorted[i]);
}
done();
});
});

Check sorting results.

unSorted[] array will have current customer name list.

sorted[] array is sorting the current customer name list.


compare sorted[] and unSorted[]

if pass then the customer list is sorted properly.


step.Then(/^Check sorting$/, (done: Callback)=> {
let sorted = [] , unSorted = [];
let cName = customerViewPage.customerNameList();
let i = 0;
cName.each(function(eachName){
eachName.getText().then(function(name){
// unSorted[i] = name.toLowerCase();
unSorted[i] = name;
i++;
});
}).then(function(){
sorted = unSorted.slice();
sorted.sort();
for(let i = 0; i < sorted.length; i++){
console.log(' Array1 : ' + sorted[i] +

' is equals to Array2 : ' + unSorted[i]);
expect(sorted[i]).is.equal(unSorted[i]);
}
done();
});
});


This step has the same functionality as above.




let statelist:any;
 let sortedStatelist:any;
 addCustomerPage.state().click().then(()=>{
   addCustomerPage.stateDropDownOptions().then(function (actualListOfStates) {
     statelist=actualListOfStates.slice();
     sortedStatelist=statelist.sort();
     // expect(statelist).to.contains(sortedStatelist);
     for(let i=0;i<sortedStatelist.length;i++){
       expect(statelist[i]).is.equal(sortedStatelist[i]);
     }
     done();
   })
 })


Fetch items from dropdown menu and check sorting status.



JavaScript Array slice() Method


var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3);


Orange,Lemon



Definition and Usage

The slice() method returns the selected elements in an array, as a new array object.

The slice() method selects the elements starting at the given start argument, and ends at, but does not include, the given end argument.

Note: The original array will not be changed.



저작자 표시 비영리 동일 조건 변경 허락
신고


Protractor For Beginners Part 1

When I started writing automated tests in Protractor, I had never programmed anything before (unless you count learning enough html/css on codecademy to create an incredibly basic, 90’s style webpage). Some of the problems I encountered whilst learning Protractor were very hard to find on Google, which did make my learning a lot slower than I would have liked. Luckily I work with amazing people who are more than happy to share their knowledge which has saved me countless times, but unfortunately there are many people out there who do not have access to such resources. So, I have decided to create a tutorial which documents as many issues as possible that I encountered whilst learning.


Protractor로 automated tests를 쓰기 시작했을 때, 나는 전혀 프로그래밍 경험이 없었다. (codecademy에서 html / css를 충분히 배우지 않아서 90년대 스타일의 아주 기초적인 html 지식만 있는 상태였다). Protractor를 배우는 동안 내가 접했던 여러 어려운 점들은 Google에서 해결책을 찾기가 어려웠다. 그래서 나의 배움은 내가 바라는 것보다 훨씬 더뎠다. 다행히도 나는 자신들의 지식을 공유하는 것을 행복하게 생각하는 많은 사람들의 도움으로 많은 정보를 얻을 수 있었다. 하지만 불행히도 그런 자료들에 접근하지 못하는 사람들도 많이 있다. 그래서, 나는 학습하면서 가능한 많은 것들을 문서화 한 tutorial을 작성하기로 결심했다.


This tutorial will be broken down into bite sized chunks, with each new blog post as a new task, and it is aimed at people with little to no experience of programming. You will be writing the tests for the AngularJs site itself, since this is a good site for practising writing Protractor tests for as it is written in AngularJs; the JavaScript framework that Protractor runs tests against.


이 튜토리얼은 각 단위별로 구분될 것이다. 그래서 각각의 새로운 블로그는 새로운 task가 될 것이다. 그럼으로서 프로그래밍에 거의 경험이 없는 사람들을 대상으로 살 것이다.  여러분들은 AngularJs 를 사용해 대한 테스트를 할 것이다. 왜냐하면 이것은 AngularJs로 작성되었기 때문에 테스트 작성을 연습하기에 아주 안성맞춤이기 때문이다. 


Note: if you get stuck at any point, the entire code can be found in https://github.com/hannimator/angularjs.org_protractor for use as reference. Snippets of the code will be shown as examples throughout.


참고 : 문제가 발생하면 https://github.com/hannimator/angularjs.org_protractor에서 전체 코드를 참조 할 수 있다. 코드의 Snippets에는 예제들이 있다.





Introduction:


To begin with, follow this tutorial https://github.com/angular/protractor/blob/master/docs/tutorial.md. It will run through how to setup Protractor and Jasmine, and the basics of running some simple tests. Another good read, but not necessary for this tutorial is https://github.com/angular/protractor/blob/master/docs/toc.md, which has some more in depth information about Protractor and Jasmine. Once you have completed the above tutorials, follow the steps below.


처음 시작할 때는 https://github.com/angular/protractor/blob/master/docs/tutorial.md)를 참조하세요. Protractor와 재스민을 설치하는 방법과 몇 가지 간단한 테스트를 실행하는 기본 사항을 설명합니다. 다른 유용한 정보들은 https://github.com/angular/protractor/blob/master/docs/toc.md 를 참조하세요.  프로트랙터와 자스민에 대해 좀 더 깊은 내용을 접할 수 있습니다. 이 튜토리얼들을 살펴보시고 난 후 아래 스텝들을 따라해 보세요.


Page Objects, Developer Tools and the DOM


Page objects model the UI objects that your test interacts with inside your tests code. Using page objects keeps the tests easier to maintain (since if anything changes, you only have to change the page objects rather than change every single test). To find these UI objects, open up the browser developer tools by pressing f12 and select the 'elements' tab, or find the element (e.g. a button), right click and select 'Inspect element' from the dropdown list. For this example, use the AngularJs site. Right click on the 'View on Github' button and select 'Inspect element'. Observe the line

   &lt;a class="btn btn-large" href="https://github.com/angular/angular.js"&gt;
      &lt;i class="icon-github-sign"&gt;&lt;/i&gt;
         "View on GitHub"
   &lt;/a&gt;
Is highlighted.

Page objects model의 UI objects는 여러분이 작성한 테스트 코드 내부와 상호작용하게 됩니다. 페이지 객체를 사용하면 테스트들을 더 쉽게 관리 할 수 있습니다 (변경 사항이 있으면 모든 단일 테스트를 변경하는 대신 페이지 객체 만 변경하면됩니다). 이러한 UI 개체를 찾으려면 f12 키를 눌러 browser developer tools을 열고  'elements' tab을 선택합니다. 혹은 element (예 : 버튼)를 찾아 마우스 오른쪽 버튼으로 클릭 한 다음 드롭 다운 목록에서 'Inspect element'를 선택합니다제. 이 예에서는 AngularJs 사이트를 사용합니다. 'View on Github' button을 마우스 오른쪽 버튼으로 클릭하고 'Inspect element'를 선택하십시오. 선이 강조 표시되어 있는지 확인하십시오.

For this element (or page object) you can see the classname is “btn btn-large”, so when you write the page object, write it like this:

이 element (또는 page object체)의 경우 클래스 이름이 "btn btn-large"라는 것을 알 수 있으므로 page object를 작성할 때 다음과 같이 작성하십시오.

       
    var pageObjectName = element(by.css(“.btn.btn-large”));
       

The reason it is written as ".btn.btn-large" rather than "btn btn-large" is down to locators, which are what tell Protractor where to find certain elements. A CSS selector would look like this: ".someCSS", whereas an ID selector would look like this: "#someID". Some more information on this can be found in the Protractor documentation

"btn btn-large"가 아닌 ".btn.btn-large"라고 쓰여진 이유는 Locator에 있습입니다. 이것은 Protractor에게 특정 elements를 어디에서 찾을지 알려주는 것입니다. CSS selector는 다음과 같이 보일 것입니다 : ".someCSS" 반면 IDselector는 "#someID"와 같이 보일 겁니다. 이것에 관한 더 많은 정보는 Protractor documentation 에서 찾을 수 있습니다.

If you want to learn a little bit more about the DOM which is mentioned throughout this tutorial, I have found https://css-tricks.com/dom/ to be a very useful and concise explanation.


이 튜토리얼에서 언급 된 DOM에 대해 조금 더 배우고 싶다면 https://css-tricks.com/dom/ 를 참조하세요. 매우 유용하고 간결한 설명이 있습니다.


Disabling Suites and Specs


To disable and enable suites and specs, simply place an x in front of the describe or the it (depending which level you want to disable the tests at, placing an x in front of the describe will disable all tests within that describe) so that it looks like this: xdescribe or xit.


suites와 specs을 disable 하게 하려면 단순히 설명 앞에 x를 표시하세요. (테스트를 사용 disable하게 할 레벨에 따라 설명 앞에 x를 붙이면 해당 설명 내의 모든 테스트가 사용 불가능하게됩니다). 다음과 같이 하시면 됩니다. : xdescribe 또는 xit.



Getting Started: Home Page


Open up https://angularjs.org/. Create a new folder where you want to keep your project. Open up your preferred text editor (I personally use Brackets), and open up the folder that you have just created. Create a new .js file called 'HomePageSpec.js' and create a config file called 'protractorConf.js'. Paste in this code in to the 'protractorConf.js' file:


https://angularjs.org/를 엽니다. 프로젝트를 keep 할 새 폴더를 만듭니다. 원하는 텍스트 편집기를 열고 방금 생성 한 폴더를 엽니다. 'HomePageSpec.js'라는 새 .js 파일을 만들고 'protractorConf.js'라는 config 파일을 만듭니다. 이 코드를 'protractorConf.js'파일에 붙여 넣습니다.


       
   exports.config = {
      seleniumAddress: 'http://localhost:4444/wd/hub',
      specs: ['HomePageObjectSpec.js'],
      onPrepare: function () {	
         browser.driver.manage().window().setSize(1680, 1050);
      },
   }
       


Task 1.1: Describe “angularjs.org should have three Center Stage buttons”


What will you learn from this task?

  • How to set up a describe suite and it spec.
  • How to create page objects.
  • How to check that something is displayed on the screen or present in the DOM using isDisplayed

여기에서 무엇을 배울 것입니까?

     describe suite와 spec을 설정하는 방법.
     페이지 객체를 만드는 방법.
     isDisplayed를 사용하여 화면에 표시되거나 DOM에 표시되는지 확인하는 방법 


In this task you will test that elements are present and visible on the page using the three center stage buttons on the home page of AngularJs.org and the Jasmine matcher .isDisplayed (read more about Jasmine matchers here. isDisplayed checks to see if the element is actually present on the page: if the element is not in the DOM whilst using isDisplayed, it will throw an exception error. See how to use isDisplayed below.


이 task에서는 AngularJs.org와 Jasmine matcher .isDisplayed의 홈 페이지에있는 3 개의 중앙 스테이지 버튼을 이용해서 해당 엘리먼트들이 페이지에 존재하고 볼수 있는지에 대해 테스트 할 것입니다.  (여기에서 Jasmine matchers에 대해 자세히 알아보십시오.) .isDisplayed는 엘리먼트가 실제로 페이지에 존재하고 보이는지를 체크합니다. : isDisplayed를 사용하는 동안 요소가 DOM에 없으면 exception error가 발생합니다. 아래의 isDisplayed 사용 방법을 참조하십시오.


  1. Open up angularjs.org
  2. Right click on the “View on GitHub” button, and select ‘Inspect element’ to bring up the html in the developer console.
  3. Find the code that relates to the “View on GitHub” button (if you hover over
       
                &lt;a class="btn btn-large" href="https://github.com/angular/angular.js"&gt;
            
    you will be able to see the button highlight).

         1. angularjs.org를 엽니 다.
         2. "View on GitHub"버튼을 마우스 오른쪽 버튼으로 클릭하고 'Inspect element'를 선택하여 개발자 콘솔에서 html을 가져옵니다.
         3. "View on GitHub"버튼과 관련된 코드를 찾습니다 (마우스를 올려 놓으면 버튼 강조 표시를 볼 수 있습니다).

  4. If you navigate up through the divs, you will be able to find the html code that contains all three elements. The class for this is center stage-buttons.
  5. In your text editor, open up your “HomePageSpec.js” file, and create a variable called HomePage like this:

        4. div를 통해 위로 이동하면 세 요소를 모두 포함하는 html 코드를 찾을 수 있습니다. 이를 위한 클래스는 중앙 스테이지 버튼입니다.
        5. 텍스트 편집기에서 "HomePageSpec.js"파일을 열고 다음과 같이 HomePage라는 변수를 만듭니다.

           
       var HomePage = function() {
     
       };
           
    This HomePage variable contains page objects, which are the elements on the page. Different page objects will be used for different sections that are tested on.

        이 HomePage 변수는 페이지의 elements인 page objects를 포함합니다. 테스트를 거친 다른 섹션에 대해 서로 다른 페이지 객체가 사용됩니다.

  6. Create page objects for the center stage buttons with the HomePage variable, like so:

        6. 다음과 같이 HomePage 변수를 사용하여 가운데 스테이지 버튼에 대한 페이지 객체를 만듭니다.

           
       var HomePage = function() { 
          this.centerStageButtons = element(by.css(".center.stage-buttons"));
    
          this.viewOnGitHubButton = this.centerStageButtons.all(by.css(".btn.btn-large")).get(0);
          this.downloadButton = this.centerStageButtons.element(by.css(".btn-primary"));
          this.designDocsButton = this.centerStageButtons.element(by.css(".btn-warning"));
       };
           

    You can see that there has been a page object created for centerStageButtons. It is good practice to write the elements as they match the code in DOM as quite often there will be multiple elements with the same name. Chaining the page objects (as above) creates more readable code as it (most of the time) eliminates the need for using .get(index). I say most of the time, since sometimes having to use .get(index) is inevitable: so if you enter in to the browser console $(".btn.btn-large") you will be able to see multiple results are returned, which is why we use .get(0) for the viewOnGitHubButton example above.

        centerStageButton에 대해 생성 된 페이지 객체가 있다는 것을 알 수 있습니다. DOM 에서 매치되면 같은 이름으로 elements들이 여러번 사용되기 쉽기 때문에 이 엘리먼트들을 사용하는 것은 좋은 방법입니다. 위와 같이 page objects를 묶는 것은 (대부분의 경우) .get (index)를 사용할 필요가 없으므로 더 읽기 쉬운 코드를 생성합니다. 대부분의 경우, 때로는 .get (색인)을 사용해야하는 것이 불가피합니다. 브라우저 콘솔 $ ( ".btn.btn-large")에 입력하면 여러 결과가 반환되는 것을 볼 수 있습니다. , 위의 viewOnGitHubButton 예제에서 .get (0)을 사용하는 이유입니다.



  7. Underneath the HomePage variable, create the test suite and spec like this:

    7. HomePage 변수 아래에 다음과 같이 테스트 suite와 spec을 작성하십시오.

    
       describe('angularjs.org', function() {
    
          beforeEach(function() {
             browser.get('https://angularjs.org/');
          });
      
          it('should have a three buttons', function() {
      
          });
       });
           
  8. In the describe, create a new HomePage object and in the it spec write the expected result of the test as below:

    8. describe에 새 HomePage 객체를 만들고 이 객체의 spec에 다음과 같이 예상되는 테스트 결과를 작성합니다.
    
       describe('angularjs.org', function() {
          var homePage = new HomePage();
    
          beforeEach(function() {
             browser.get('https://angularjs.org/');
          });
      
          it('should have a three buttons', function() {
             expect(homePage.viewOnGitHubButton.isDisplayed()).toBe(true);
          });
       });
           
  9. Run the test by opening up the command line, navigating to the folder where the config file is located. Type in protractor protractorConf.js and press Enter for the code to start running (make sure you have started the selenium webdriver by typing in webdriver-manager start and pressing enter in the command line).

    9. command line을 열고 config 파일이있는 폴더로 이동하여 테스트를 실행하십시오. 코드를 실행하려면 protractor protractorConf.js를 입력하고 Enter 키를 누릅니다 (webdriver-manager start를 입력하고 명령 행에서 Enter 키를 눌러 selenium webdriver를 시작했는지 확인하십시오).

  10. Did it pass? Yes? Great! No? Double check you have the code written correctly by looking at the code inside the Spec folder here: https://github.com/hannimator/angularjs.org_protractor .

    10. 통과 했습니까? 예? 좋습니다! 아니요? Spec 폴더의 코드 (https://github.com/hannimator/angularjs.org_protractor)를보고 코드가 올바르게 작성되었는지 다시 확인하십시오.

  11. Now that this test has passed, it is always best to check that it fails if set to false, so underneath the first expect, create another one set to false like this:

    11. 이제 이 테스트가 통과되었으므로 false로 설정하면 실패하는지 확인하는 것이 가장 좋습니다. 따라서 첫 번째 기대치 아래에서 다음과 같이 false로 설정된 또 다른 하나를 만듭니다.
           
       expect(homePage.viewOnGitHubButton.isDisplayed()).toBe(false);
           
  12. Run the test. Observe the expect set to false fails. This ensures that it isn’t a false positive, and is always a good practice to ensure that you haven't missed anything in your code.

    12. 테스트를 실행하십시오. expect가 false로 설정된 것을 확인하십시오. 이렇게하면 false positive가 아니라는 것을 알 수 있습니다. 그리고 코드에서 아무 것도 놓치지 않았는지 확인할 수 있는 좋은 방법입니다.

In the next tutorial we will use what we learnt in this tutorial and start to learn how to interact with elements on the webpage, as well as the difference between using the matchers isPresent and isDisplayed.

다음 튜토리얼에서는이 튜토리얼에서 배운 것을 사용하고 웹 페이지에서 요소와 상호 작용하는 방법을 배우기 시작할 것이고, isPresent와 isDisplayed라는 matcher를 사용하는 것의 차이점도 알게 될 것이다.


저작자 표시 비영리 동일 조건 변경 허락
신고
이전 1 다음