블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 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 31      


The Hamcrest Tutorial



Introduction

Hamcrest is a framework for writing matcher objects allowing 'match' rules to be defined declaratively. There are a number of situations where matchers are invaluble, such as UI validation, or data filtering, but it is in the area of writing flexible tests that matchers are most commonly used. This tutorial shows you how to use Hamcrest for unit testing.


Hamcrest는 'match'rule을 선언적으로 정의 해 matcher objects를 작성하기위한 framework입니다. UI 유효성 UI validation 또는 데이터 필터링과 같이 matchers가 사용할 수 없는 상황도 많이 있지만 matcher가 가장 일반적으로 사용되는 곳은 flexible tests를 작성하는 영역에 있습니다. 이 tutorial에서는 unit testing를 위해 Hamcrest를 사용하는 방법을 보여줍니다.


When writing tests it is sometimes difficult to get the balance right between overspecifying the test (and making it brittle to changes), and not specifying enough (making the test less valuable since it continues to pass even when the thing being tested is broken). Having a tool that allows you to pick out precisely the aspect under test and describe the values it should have, to a controlled level of precision, helps greatly in writing tests that are "just right". Such tests fail when the behaviour of the aspect under test deviates from the expected behaviour, yet continue to pass when minor, unrelated changes to the behaviour are made.


테스트를 작성할 때 테스트를 지나치게 자세하게 지정하는 것 (그리고 수정이 어렵게 하는 것)과 충분한 테스트를 하지 않는 것 사이의 균형을 잡기가 어렵기 때문에 (이럴 경우 테스트 대상에 문제가 생긴 경우에도 테스트가 pass 될 수 있어 해당 테스트가 유효하지 않게 됩니다.) 테스트 할 aspect를 정확하게 선택할 수 있도록 하고, 가져야 할 값을 describe 해서 정밀하게 제여할 수 있도록 하는 도구를 사용하면 "just right" 테스트를 작성하는 데 크게 도움이됩니다. 이러한 테스트는 테스트중인 aspect의 동작이 예상되는 벗어나는 경우 fail 하고 , minor 한 변화나 테스트 범위에서 벗어난 변경이 있는 경우 pass 해야 합니다.



My first Hamcrest test

We'll start by writing a very simple JUnit 3 test, but instead of using JUnit's assertEquals methods, we use Hamcrest's assertThatconstruct and the standard set of matchers, both of which we statically import:


아래 간단한 JUnit 3 test를 작성할 겁니다. JUnit의 assertEquals methods를 사용하는 대신에 Hamcrest의 assertThat construct와 matchers의 표준 세트를 사용할 겁니다. 이 둘은 정적으로 import 합니다.



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


import junit.framework.TestCase;


public class BiscuitTest extends TestCase { public void testEquals() { Biscuit theBiscuit = new Biscuit("Ginger"); Biscuit myBiscuit = new Biscuit("Ginger"); assertThat(theBiscuit, equalTo(myBiscuit)); } } ```



The assertThat method is a stylized sentence for making a test assertion. In this example, the subject of the assertion is the object biscuit that is the first method parameter. The second method parameter is a matcher for Biscuit objects, here a matcher that checks one object is equal to another using the Object equals method. The test passes since the Biscuit class defines an equals method.


assertThat method는 test assertion을 만들기 위한 양식화 된 문장입니다. 이 예에서는 assertion의 subject는 첫 번째 method 매개 변수 인 object biscuit입니다. 두 번째 method 매개 변수는 Biscuit objects에 대한 matcher입니다. 여기에서 한 object를 검사하는 matcher는 Object equals method를 사용하는것과 같습니다. 이 테스트는 Biscuit 클래스가 equals method를 정의하기 때문에 pass 하게 됩니다.



If you have more than one assertion in your test you can include an identifier for the tested value in the assertion:


하나 이상의 assertion이 있는 경우 테스트 된 값에 대한 identifier를 assertion에 포함 할 수 있습니다.


assertThat("chocolate chips", theBiscuit.getChocolateChipCount(), equalTo(10)); assertThat("hazelnuts", theBiscuit.getHazelnutCount(), equalTo(3));



Other test frameworks



Hamcrest has been designed from the outset to integrate with different unit testing frameworks. For example, Hamcrest can be used with JUnit 3 and 4 and TestNG. (For details have a look at the examples that come with the full Hamcrest distribution.) It is easy enough to migrate to using Hamcrest-style assertions in an existing test suite, since other assertion styles can co-exist with Hamcrest's.


Hamcrest는 처음부터 다른 unit testing framework와 통합되도록 설계되었습니다. 예를 들어, Hamcrest는 JUnit 3과 4 및 TestNG와 함께 사용할 수 있습니다. (자세한 내용은 전체 Hamcrest distribution과 함께 제공되는 예제를 참조하십시오.) 다른 assertion 스타일이 Hamcrest와 같이 사용될 수 있기 때문에 기존 test suite에서 Hamcrest-style assertions를 사용하는 것으로 마이그레이션하는 것은 쉽습니다.


Hamcrest can also be used with mock objects frameworks by using adaptors to bridge from the mock objects framework's concept of a matcher to a Hamcrest matcher. For example, JMock 1's constraints are Hamcrest's matchers. Hamcrest provides a JMock 1 adaptor to allow you to use Hamcrest matchers in your JMock 1 tests. JMock 2 doesn't need such an adaptor layer since it is designed to use Hamcrest as its matching library. Hamcrest also provides adaptors for EasyMock 2. Again, see the Hamcrest examples for more details.


Hamcrest는 또한 mock objects framework와 같이 사용 될 수 있습니다. 그러려면 mock objects framework의 matcher와 Hamcrest의 matcher 에 대한 concept을 연결해 주도록 adaptors를 사용하면 됩니다. 예를 들어, JMock 1의 constraints는 Hamcrest의 matchers입니다. Hamcrest는 JMock 1 테스트에서 Hamcrest matchers를 사용할 수 있도록 JMock 1 어댑터를 제공합니다. JMock 2는 Hamcrest를 매칭 라이브러리로 사용하기 때문에 그러한 adaptor layer가 필요하지 않습니다. Hamcrest는 EasyMock 2 용 어댑터도 제공합니다. 자세한 내용은 Hamcrest 예제를 참조하십시오.



A tour of common matchers



Hamcrest comes with a library of useful matchers. Here are some of the most important ones.


Hamcrest는 유용한 matchers 라이브러리를 제공합니다. 그 중에 중요한 것들 입니다.



    Core
    • anything - always matches, useful if you don't care what the object under test is
    • describedAs - decorator to adding custom failure description
    • is - decorator to improve readability - see "Sugar", below

  • Logical
    • allOf - matches if all matchers match, short circuits (like Java &&)
    • anyOf - matches if any matchers match, short circuits (like Java ||)
    • not - matches if the wrapped matcher doesn't match and vice versa

  • Object
    • equalTo - test object equality using Object.equals
    • hasToString - test Object.toString
    • instanceOfisCompatibleType - test type
    • notNullValuenullValue - test for null
    • sameInstance - test object identity

  • Beans
    • hasProperty - test JavaBeans properties

  • Collections
    • array - test an array's elements against an array of matchers
    • hasEntryhasKeyhasValue - test a map contains an entry, key or value
    • hasItemhasItems - test a collection contains elements
    • hasItemInArray - test an array contains an element

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

  • Text
    • equalToIgnoringCase - test string equality ignoring case
    • equalToIgnoringWhiteSpace - test string equality ignoring differences in runs of whitespace
    • containsStringendsWithstartsWith - test string matching



Sugar


Hamcrest strives to make your tests as readable as possible. For example, the is matcher is a wrapper that doesn't add any extra behavior to the underlying matcher. The following assertions are all equivalent:


Hamcrest는 여러분이 최대한 readable한 테스트를 만들 수 있도록 노력합니다. 예를 들어, is matcher는 기본이되는 matcher에 추가의 동작을 추가하지 않는 wrapper 입니다. (어떤 동작을 하지는 않고 단지 가독성 -readable- 을 제공하기 위한 것).

아래 assertion 들은 다 똑 같습니다.



assertThat(theBiscuit, equalTo(myBiscuit)); assertThat(theBiscuit, is(equalTo(myBiscuit))); assertThat(theBiscuit, is(myBiscuit));


The last form is allowed since is(T value) is overloaded to return is(equalTo(value)).


마지막 form은 is(T value)가 is(equalTo (value))를 return하도록 overload 되어 있기 때문에 가능합니다.



Writing custom matchers



Hamcrest comes bundled with lots of useful matchers, but you'll probably find that you need to create your own from time to time to fit your testing needs. This commonly occurs when you find a fragment of code that tests the same set of properties over and over again (and in different tests), and you want to bundle the fragment into a single assertion. By writing your own matcher you'll eliminate code duplication and make your tests more readable!


Hamcrest는 많은 유용한 matchers와 함께 번들로 제공되지만, 테스트 요구에 맞추기 위해 수시로 자신 만의 템플릿을 만들어야 할 필요가있을 것입니다. 이것은 일반적으로  동일한 properties set을 반복적으로 테스트 하는 (다른 테스트 들에서도) code의 fragment를 발견 했을 때 그리고 이 fragment를 단일 assertion으로 묶으려는 경우에 해당 될 겁니다. 자신 만의 matcher를 작성함으로써 코드 중복을 제거하고 테스트의 가독성을 훨씬 높일 수 있습니다!



Let's write our own matcher for testing if a double value has the value NaN (not a number). This is the test we want to write:


double 값의 값이 NaN (숫자가 아님) 인 경우를 테스트하기 위해 자체 matcher를 작성해 보겠습니다. 아래 그 예제가 있습니다.



public void testSquareRootOfMinusOneIsNotANumber() { assertThat(Math.sqrt(-1), is(notANumber())); }


And here's the implementation:


``` package org.hamcrest.examples.tutorial;

import org.hamcrest.Description; import org.hamcrest.Factory; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher;

public class IsNotANumber extends TypeSafeMatcher {

@Override public boolean matchesSafely(Double number) { return number.isNaN(); }

public void describeTo(Description description) { description.appendText("not a number"); }

@Factory public static Matcher notANumber() { return new IsNotANumber(); }

} ```



The assertThat method is a generic method which takes a Matcher parameterized by the type of the subject of the assertion. We are asserting things about Double values, so we know that we need a Matcher<Double>. For our Matcher implementation it is most convenient to subclass TypeSafeMatcher, which does the cast to a Double for us. We need only implement the matchesSafely method - which simply checks to see if the Double is NaN - and the describeTo method - which is used to produce a failure message when a test fails. Here's an example of how the failure message looks:


assertThat method는, assertion의 subject의 type에 의해 파라미터 화 된 Matcher를 취하는 generic method입니다. 우리는 Double 값에 대해 asserting하고 있으므로 Matcher <Double>이 필요하다는 것을 알고 있습니다. 이 Matcher를 구현하는데 있어 TypeSafeMatcher를 서브 클래스로 implement 하는 것이 가장 좋습니다. TypeSafeMatcher는 Double로 형변환을 하게 됩니다. matchesSafely method와 describeTo method만 implement 하면 됩니다. matchesSafely method는 단순히 Double이 NaN인지 확인하고 describeTo method 테스트가 fail 할 경우 오류 메시지를 생성하는 데 사용됩니다. 다음은 failure message가 표시되는 예입니다.



assertThat(1.0, is(notANumber()));


fails with the message


java.lang.AssertionError: Expected: is not a number got : <1.0>



The third method in our matcher is a convenience factory method. We statically import this method to use the matcher in our test:


우리의 matcher에서 세 번째 method는 편리한 factory method 입니다. test에서 matcher를 사용하기 위해 이 method를 정적(statically)으로 가져옵니다.


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

import static org.hamcrest.examples.tutorial.IsNotANumber.notANumber;

import junit.framework.TestCase;

public class NumberTest extends TestCase {

public void testSquareRootOfMinusOneIsNotANumber() { assertThat(Math.sqrt(-1), is(notANumber())); } } ```



Even though the notANumber method creates a new matcher each time it is called, you should not assume this is the only usage pattern for your matcher. Therefore you should make sure your matcher is stateless, so a single instance can be reused between matches.


비록 notANumber method가 호출 될 때마다 new matcher를 생성하지만, 이것이 matcher의 유일한 사용 patter 이라고 예단 해서는 안됩니다. 여러분은 이 matcher가 stateless 임을 유념해야 합니다. single instance 가 matcher들 사이에서 재사용 될 수 있습니다.



Sugar generation



If you produce more than a few custom matchers it becomes annoying to have to import them all individually. It would be nice to be able to group them together in a single class, so they can be imported using a single static import much like the Hamcrest library matchers. Hamcrest helps out here by providing a way to do this by using a generator.


여러가지 custom matchers를 만들었다면 이들을 각각 import 하는 일이 성가실 겁니다. 하나의 클래스에서 이들을 그룹화 하면 좋겠죠. 그렇게 하면 Hamcrest 라이브러리 matchers와 같이 single static import를 사용하여 한꺼번에 import 할 수 있을 겁니다. Hamcrest는 generator를 사용하여 이를 수행 할 수있는 방법을 제공합니다.


First, create an XML configuration file listing all the Matcher classes that should be searched for factory methods annotated with the org.hamcrest.Factory annotation. For example:


먼저, 모든 Matcher classes을 리스팅 한 XML configuration file을 생성합니다. 이것은 org.hamcrest.Factory annotation과 함께 factory methods annotated를 하기 위해 검색 될 겁니다. 예 :


```

```


Second, run the org.hamcrest.generator.config.XmlConfigurator command-line tool that comes with Hamcrest. This tool takes the XML configuration file and generates a single Java class that includes all the factory methods specified by the XML file. Running it with no arguments will display a usage message. Here's the output for the example.


둘째, Hamcrest와 함께 제공되는 org.hamcrest.generator.config.XmlConfigurator command-line tool를 실행하십시오. 이 도구는 XML 구성 파일을 사용하여 XML 파일에 지정된 모든 팩토리 method를 포함하는 단일 Java 클래스를 생성합니다. 인수없이 실행하면 사용법 메시지가 표시됩니다. 이 예제의 결과는 다음과 같습니다.



``` // Generated source. package org.hamcrest.examples.tutorial;

public class Matchers {

public static org.hamcrest.Matcher is(T param1) { return org.hamcrest.core.Is.is(param1); }

public static org.hamcrest.Matcher is(java.lang.Class param1) { return org.hamcrest.core.Is.is(param1); }

public static org.hamcrest.Matcher is(org.hamcrest.Matcher param1) { return org.hamcrest.core.Is.is(param1); }

public static org.hamcrest.Matcher notANumber() { return org.hamcrest.examples.tutorial.IsNotANumber.notANumber(); }

} ```



Finally, we can update our test to use the new Matchers class.


마지막으로 new Matchers class를 사용하도록 아래처럼 업데이트 합니다.



``` import static org.hamcrest.MatcherAssert.assertThat;

import static org.hamcrest.examples.tutorial.Matchers.*;

import junit.framework.TestCase;

public class CustomSugarNumberTest extends TestCase {

public void testSquareRootOfMinusOneIsNotANumber() { assertThat(Math.sqrt(-1), is(notANumber())); } } ```



Notice we are now using the Hamcrest library is matcher imported from our own custom Matchers class.


Notice 우리는 custom Matchers class 에서 importe된 matcher 인 Hamcrest library를 사용하게 됩니다.



Where next?

See FurtherResources.

--Tom White

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


Asynchronous Testing with Protractor’s ControlFlow


Protractor is an end-to-end testing framework for AngularJS applications that uses a real browser, just as a real user would. It is built on top of NodeJS and WebDriverJS and taps into the internals of Angular to know when Angular is done processing and updating bindings.



Protractor는 real user would와 마찬가지로 실제 브라우저를 사용하는 AngularJS 응용 프로그램의 end-to-end testing framework입니다. NodeJS 및 WebDriverJS 위에 구축되며 Angular의 내부를 tap해서 Angular가 바인딩 처리 및 업데이트를 완료 한 시점을 알 수 있습니다.


The joy of Protractorand WebDriverJS is that we can write our tests in a synchronous style, and still have the added benefits of asynchronous code. 


Protractor와 WebDriverJS의 강점은 동기식 스타일로 테스트를 작성할 수 있으며 비동기 코드의 부가적인 이점을 여전히 가지고 있다는 것입니다.

We are currently using Protractor for testing a Rails and Angular application that we’re developing here in the Detroit office. We were faced with a problem: “How do we write our own functions which are asynchronous but appear in the same synchronous style that Protractor tests are written in?” This is especially handy for performing REST requests for seeding data into the test database using something like the rails Hangar gem. 


우리는 현재 디트로이트 사무실에서 개발중인 Rails 및 Angular 응용 프로그램을 테스트하기 위해 Protractor를 사용하고 있습니다. "비동기식이지만 Protractor로 작성된 동기식으로 보이는 함수는 어떻게 작성합니까"  이것은 rails Hangar gem 같은 것을 사용해서 테스트 데이터베이스에 데이터를 넣기 위한 REST requests를 수행 할 때 특히 유용합니다. 


The ControlFlow


This required diving into the internals of how Protractor and WebDriverJS handle asynchrony. WebDriverJS uses an object called theControlFlow, which coordinates the scheduling and execution of commands operating on a queue. 


Any time an asynchronous command is invoked, it’s put in the queue where it will wait for all previous commands to complete prior to execution. The ControlFlow allows us to write code like this:


Protractor와 WebDriverJS가 어떻게 비동기를 처리하는지에 대해 좀 더 깊이 들어가겠습니다. WebDriverJS는 theControlFlow라는 객체를 사용합니다. 이 객체는 queue에서 작동하는 명령의 일정과 실행을 조정합니다.


비동기 명령이 호출 될 때마다 queue에 저장되어 실행 되기 전 모든 이전 명령들이 완료 될 때까지 대기합니다. ControlFlow를 사용하면 다음과 같은 코드를 작성할 수 있습니다.


driver.get(“http://www.google.com”);
driver.findElement(webdriver.By.name('q')).sendKeys('webdriver');
driver.findElement(webdriver.By.name('btnG')).click();
driver.getTitle().then(function(title) {
  console.log(title);
});


That really performs in a synchronous manner such as this:

이것은 아래와 같이 동기화 방식으로 처리 됩니다.


driver.get(“http://www.google.com”).
    then(function() {
      return driver.findElement(webdriver.By.name('q'));
    }).
    then(function(q) {
      return q.sendKeys('webdriver');
    }).
    then(function() {
      return driver.findElement(webdriver.By.name('btnG'));
    }).
    then(function(btnG) {
      return btnG.click();
    }).
    then(function() {
      return driver.getTitle();
    }).
    then(function(title) {
      console.log(title);
    });


Behind the scenes of WebDriver, each call that interacts with the browser, such as get()findElement()sendKeys(), and click(), is being scheduled and pushed onto the WebDriver ControlFlow, allowing us to not have to worry about using .then() on the resulting promises (unless we specifically want the result returned by the call). 

WebDriver의 이면에서 get (), findElement (), sendKeys () 및 click ()과 같이 브라우저와 상호 작용하는 각 호출이 예약되고 WebDriver ControlFlow에 푸시되므로 resulting promises 에 대해 걱정할 필요가 없습니다 (호출에 의해 반환 된 결과가 특별히 필요하지 않는 한)


Using the WebDriverJS Promises



The ControlFlow queues functions based on promises. The following code exhibits how to take a callback based function and wrap it into WebDriver’s Promise API. We will be using the Restler NodeJS library.


ControlFlow 대기열 기능은 promises를 기반으로합니다. 아래 코드는 callback 기반 함수를 WebDriver의 Promise API로 래핑하는 방법을 보여줍니다. 우리는 Restler NodeJS 라이브러리를 사용할 것입니다.

To create a WebDriver/Protractor deferred using their promise API:

promise API를 사용하여 지연된 WebDriver / Protractor를 만들려면 :


deferred = protractor.promise.defer()


Then fullfill or reject the promise based on Restler’s events and return the deferred promise:


restler.postJson(url, requestData, options).once('success', function() {
  return deferred.fulfill();
}).once('error', function() {
  return deferred.reject();
}).once('fail', function() {
  return deferred.reject();
});
 
deferred.promise;


Pushing the Promise Onto the ControlFlow



To solve our problem of invoking a synchronous REST request, we have to interact with WebDriver’s ControlFlow. 

To get the instance of the ControlFlow that is shared with protractor:


synchronous REST request를 invoking하는 문제를 해결하려면 WebDriver의 ControlFlow와 상호 작용해야합니다.

Protractor와 공유되는 ControlFlow의 인스턴스를 얻으려면 :


var flow = browser.controlFlow()


Then we can use the ControlFlow’s execute() function, assuming we created a based on the above code that wraps restler’s callbacks and returns a WebDriverJS promise:


그런 다음 Restler의 콜백을 래핑하고 WebDriverJS 약속을 반환하는 위 코드를 기반으로 ControlFlow의 execute () 함수를 사용할 수 있다고 가정합니다.


flow.execute(restFunction)


Chaining Promises and Getting Results



The good news is that ControlFlow’s execute() function returns a new promise that will be fulfilled when our original promise is executed by the scheduler. We can use use the all() function, which returns a new promise once all of the control flow’s promises are fulfilled:

좋은 소식은 ControlFlow의 execute () 함수가 새 promise를 반환한다는 겁니다. 이렇게 함으로서 원래 약속이 스케줄러에 의해 실행될 때 수행 될 이 조건이 충족되게 됩니다. 모든 control flow의 promises가 충족 됐을 때 new promise 가 반환되는 all () 함수를 사용할 수 있습니다.


var allPromise = protractor.promise.all(flow.execute(restFunction1), flow.execute(restFunction2))



When allPromise is fulfilled, it will return an array of the results of all the promises passed to all() as arguments. 

allPromise가 수행되면 all ()에 전달 된 모든 promises의 결과 배열을 인수로 반환합니다.


Ideally the implementation of your helper functions would abstract the intermediary promises that are being passed to the ControlFlow and purely operate based upon the promises returned from the ControlFlow’s execute function.

이상적으로 helper 함수의 구현은 ControlFlow로 전달되는 intermediary promises을 abstract화하고 ControlFlow의 실행 함수에서 반환 된 promises를 기반으로 작동합니다.


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


Simple version of LED Light stand base for 3D crystal laser cube



I have Taj Mahal 3D crystal laser Cube.

You can get it from ebay also.





I found there are many stand bases for these kind of 3D crystal cube and it makes gorgeous view of it. like below.



So I've decided to develop it using Arduino.


The result is this.





This is the Source code.


/*

  For LED Light stand for 3D Crystal laser cube


  version : 0.4


  created 03 May 2017


  by Douglas Changsoo Park

*/


// Define Pins

#define RED1 3

#define GREEN1 4

#define BLUE1 5

#define RED2 6

#define GREEN2 7

#define BLUE2 8

#define delayTime 100


// define variables

int redValue1;

int greenValue1;

int blueValue1;

int redValue2;

int greenValue2;

int blueValue2;


void setup() {

  pinMode(RED1, OUTPUT);

  pinMode(GREEN1, OUTPUT);

  pinMode(BLUE1, OUTPUT);

  digitalWrite(RED1, HIGH);

  digitalWrite(GREEN1, HIGH);

  digitalWrite(BLUE1, HIGH);


  pinMode(RED2, OUTPUT);

  pinMode(GREEN2, OUTPUT);

  pinMode(BLUE2, OUTPUT);

  digitalWrite(RED2, HIGH);

  digitalWrite(GREEN2, HIGH);

  digitalWrite(BLUE2, HIGH);


  redValue1 = random(1, 255);

  greenValue1  = random(1, 255);

  blueValue1  = random(1, 255);

  redValue2 = random(1, 255);

  greenValue2  = random(1, 255);

  blueValue2  = random(1, 255);

}


void loop() {

  LEDLights(redValue1, greenValue1, blueValue1, redValue2, greenValue2, blueValue2);

  delay(delayTime * 4);

}


void LEDLights(int red1, int green1, int blue1, int red2, int green2, int blue2) {


  redValue1 = red1;

  greenValue1 = green1;

  blueValue1 = blue1;

  redValue2 = red2;

  greenValue2 = green2;

  blueValue2 = blue2;


  int redResult1 = randomValue(redValue1);

  int greenResult1 = randomValue(greenValue1);

  int blueResult1 = randomValue(blueValue1);


  int redResult2 = randomValue(redValue2);

  int greenResult2 = randomValue(greenValue2);

  int blueResult2 = randomValue(blueValue2);


  for (int i = 0; i < 25; i += 1) {

    analogWrite(RED1, redValue1 + redResult1);

    analogWrite(GREEN1, greenValue1 + greenResult1);

    analogWrite(BLUE1, blueValue1 + blueResult1);

    analogWrite(RED2, redValue2 + redResult2);

    analogWrite(GREEN2, greenValue2 + greenResult2);

    analogWrite(BLUE2, blueValue2 + blueResult2);


    redValue1 = redValue1 + redResult1;

    greenValue1 = greenValue1 + greenResult1;

    blueValue1 = blueValue1 + blueResult1;

    redValue2 = redValue2 + redResult2;

    greenValue2 = greenValue2 + greenResult2;

    blueValue2 = blueValue2 + blueResult2;


    delay(delayTime);

  }

}


int randomValue(int value) {

  int result;

  int minN;

  int maxN;


  int interval = random(1, 5);


  if (interval == 1) {

    minN = 26;

    maxN = 229;

  } else if (interval == 2) {

    minN = 51;

    maxN = 204;

  } else if (interval == 3) {

    minN = 76;

    maxN = 179;

  } else if (interval == 4) {

    minN = 101;

    maxN = 154;

  } else {

    minN = 126;

    maxN = 129;

  }


  if (value < minN) {

    result = interval;

  } else if (value > maxN) {

    result = -interval;

  } else {

    int randomVal = random(0, 1);

    if (randomVal == 0) {

      result = interval;

    } else {

      result = -interval;

    }

  }


  return result;

}




I wanted to make a combination and change of a more varied and softer color using random() in randomValue() function.


LEDLights() function will turn on and change the LED Light with the return value of the randomValue() function.


The loop() function will call the LED LIghts() function repeatedly every given time.


The components will be configured as below.





I've used Arduino Nano, 12V battery pack with 8 AAA batteries, 1 car charger adapter, small bread board and 2 RGB LEDs.


all parts are what I already have. 


It will cost about $ 15 for a new purchase.



Link to my project in hackster.


https://www.hackster.io/solkit/portable-led-light-stand-for-3d-crystal-laser-cube-5d8bd1







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


I don't like you

Practice scripting for the project 'I like you'


Source Code


/*

  For I don't like you. (practice project for the project 'I like you')


  version : 0.1


  created 07 May 2017


  by Douglas Changsoo Park

*/


#include <Servo.h>

#include <NewPing.h>


#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.

#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.

#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.


NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

Servo myservo;//create servo object to control a servo


int distance;


void setup() {

  myservo.attach(9);//attachs the servo on pin 9 to servo object

  myservo.write(0);//back to 0 degrees 

  delay(1000);//wait for a second


  Serial.begin(9600); // Open serial monitor at 115200 baud to see ping results.

}


void loop() {

  delay(500);  // 

  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).

  Serial.print("Ping: ");

  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)

  Serial.println("cm");

 

  distance = uS / US_ROUNDTRIP_CM;


  delay(500);

  // Servo motor moves when the distance is less than 5cm

  if (distance < 5 && distance != 0) {

    Serial.println("distance : ");

    Serial.println(distance); 

    myservo.write(90);//goes to 45 degrees 

    delay(500);

    myservo.write(-90);//goes to 45 degrees

    delay(500);

  }


}


==> Servo motor will move 90 degree and -90 degree when ultrasonic sensor detects object (person) in 5 cm.
Ultrasonic sonic sensor is going to be a pet's head so it looks like the pet is shaking his head because he doesn't like the person.

==> This is practice project of the project "I like you"
with the project, As you move, the pet will keep looking at you.
So the project name is "I like you" 

==> to do that I am planning to use 2 (or 3) ultrasonic sensor.

Anyway for the practice project "I don't like you", Arduino components should be configured as follows.



It will print the distance in 'cm' if it is run.




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







Testing and validating REST services in Java is harder than in dynamic languages such as Ruby and Groovy. REST Assured brings the simplicity of using these languages into the Java domain. For example if your HTTP server returns the following JSON at “http://localhost:8080/lotto/{id}”:


Ruby 및 Groovy와 같은 동적 언어보다 Java에서 REST 서비스를 테스트하고 유효성을 검사하는 것은 더 어렵습니다. REST Assured는 이러한 언어를 Java 도메인에서

 사용하는 간단한 방법을 제공합니다. 예를 들어 HTTP 서버가 "http : // localhost : 8080 / lotto / {id}"에 다음 JSON을 반환하는 경우 :


{
   "lotto":{
      "lottoId":5,
      "winning-numbers":[2,45,34,23,7,5,3],
      "winners":[
         {
            "winnerId":23,
            "numbers":[2,45,34,23,3,5]
         },
         {
            "winnerId":54,
            "numbers":[52,3,12,11,18,22]
         }
      ]
   }
}


You can easily use REST Assured to validate interesting things from the response:

REST Assured를 사용하여 response에서 원하는 것을 검증 할 수 있습니다.


@Test public void
lotto_resource_returns_200_with_expected_id_and_winners() {
    
    when().
            get("/lotto/{id}", 5).
    then().
            statusCode(200).
            body("lotto.lottoId", equalTo(5), 
                 "lotto.winners.winnerId", containsOnly(23, 54));

}


Looks easy enough? Why not give it a spin? See getting starting and usage guide.


정말 쉽죠? 널리 알려 주세요? getting starting 및 usage guide를 참조하세요.





Getting Started


Maven / Gradle Users


Add the following dependency to your pom.xml:


아래 dependency를 pom.xml에 추가하세요.


REST Assured

Includes JsonPath and XmlPath

Maven:

<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>rest-assured</artifactId>
      <version>3.0.3</version>
      <scope>test</scope>
</dependency>

Gradle:

testCompile 'io.rest-assured:rest-assured:3.0.3'

Notes

  1. You should place rest-assured before the JUnit dependency declaration in your pom.xml / build.gradle in order to make sure that the correct version of Hamcrest is used.
  2. REST Assured includes JsonPath and XmlPath as transitive dependencies
Notes

1. Hamcrest의 올바른 버전이 사용되는지 확인하기 위해 pom.xml / build.gradle에서 JUnit dependency declaration 앞에 rest-assured를 넣어야 합니다.
2. REST Assured는 JsonPath 및 XmlPath를 transitive dependencies로 include합니다.

JsonPath


Standalone JsonPath (included if you depend on the rest-assured artifact). Makes it easy to parse JSON documents. Note that this JsonPath implementation uses Groovy's GPath syntax and is not to be confused with Kalle Stenflo's JsonPath implementation.

Standalone JsonPath (rest-assured artifact에 의존하는 경우 포함됨). 이렇게 함으로서 JSON 문서를 쉽게 파싱 할 수 있습니다. 이 JsonPath 구현은 Groovy의 GPath 구문을 사용하므로 Jayway의 다른 JsonPath 구현과 혼동하지 않아야합니다.


Maven:

<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>json-path</artifactId>
      <version>3.0.3</version>
</dependency>

Gradle:

compile 'io.rest-assured:json-path:3.0.3'


XmlPath


Stand-alone XmlPath (included if you depend on the rest-assured artifact). Makes it easy to parse XML documents.

 Stand-alone XmlPath (rest-assured artifact에 의존하는 경우 포함됨). 이렇게 함으로서 XML 문서를 쉽게 파싱 할 수 있습니다.


Maven:

<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>xml-path</artifactId>
      <version>3.0.3</version>
</dependency>

Gradle:

compile 'io.rest-assured:xml-path:3.0.3'


JSON Schema Validation


If you want to validate that a JSON response conforms to a Json Schema you can use the json-schema-validator module:

JSON 응답이 Json Schema를 따르는 지 확인하려면 json-schema-validator 모듈을 사용할 수 있습니다.


Maven:

<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>json-schema-validator</artifactId>
      <version>3.0.3</version>
      <scope>test</scope>
</dependency>

Gradle:

testCompile 'io.rest-assured:json-schema-validator:3.0.3'


Refer to the documentation for more info.

자세한 내용은 설명서를 참조하십시오.


Spring Mock Mvc


If you're using Spring Mvc you can now unit test your controllers using the RestAssuredMockMvc API in the spring-mock-mvc module. For this to work you need to depend on the spring-mock-mvc module:

Spring Mvc를 사용하고 있다면 Spring Mock-mvc 모듈의 RestAssuredMockMvc API를 사용하여 controllers를 유닛 테스트 할 수 있습니다. 이 작업을 하기 위해서는 spring-mock-mvc 모듈에 의존해야합니다.


Maven:

<dependency>
      <groupId>io.rest-assured</groupId>
      <artifactId>spring-mock-mvc</artifactId>
      <version>3.0.3</version>
      <scope>test</scope>
</dependency>

Gradle:

testCompile 'io.rest-assured:spring-mock-mvc:3.0.3'


Scala Support


If you're using Scala you may leverage the scala-support module. For this to work you need to depend on the scala-support module:


Scala를 사용하는 경우 Scala 지원 모듈을 활용할 수 있습니다. 이 작업을 수행하려면 scala-support 모듈에 의존해야합니다.


SBT:

libraryDependencies += "io.rest-assured" % "scala-support" % "3.0.3"

Maven:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>scala-support</artifactId>
    <version>3.0.3</version>
    <scope>test</scope>
</dependency>

Gradle:

testCompile 'io.rest-assured:scala-support:3.0.3'


Non-maven users


Download REST Assured and Json Schema Validator (optional). You can also download XmlPath and/or JsonPath separately if you don't need REST Assured. If you're using Spring Mvc then you can download the spring-mock-mvc module as well. If you're using Scala you may optionally download the scala-support module. Extract the distribution zip file and put the jar files in your class-path.


REST Assured 및 Json Schema Validator (선택 사항)를 다운로드하십시오. REST Assured가 필요하지 않은 경우 XmlPath 와 JsonPath를 별도로 다운로드 할 수도 있습니다. 당신이 Spring Mvc를 사용하고 있다면 당신은 spring-mock-mvc 모듈을 다운로드 할 수있습니다. Scala를 사용하는 경우 선택적으로 Scala 지원 모듈을 다운로드 할 수 있습니다. 배포 zip 파일의 압축을 풀고 jar 파일을 클래스 경로에 넣습니다.





Static imports


In order to use REST assured effectively it's recommended to statically import methods from the following classes:

REST assured를 효과적으로 사용하려면 다음 클래스에서 메소드를 정적으로 가져 오는 것이 좋습니다.


io.restassured.RestAssured.*
io.restassured.matcher.RestAssuredMatchers.*
org.hamcrest.Matchers.*


If you want to use Json Schema validation you should also statically import these methods:

Json Schema 유효성 검사를 사용하려면 다음 메소드를 정적으로 가져와야합니다.


io.restassured.module.jsv.JsonSchemaValidator.*


Refer to Json Schema Validation section for more info.

자세한 내용은 Json 스키마 유효성 검사 섹션을 참조하십시오.


If you're using Spring MVC you can use the spring-mock-mvc module to unit test your Spring Controllers using the Rest Assured DSL. To do this statically import the methods from RestAssuredMockMvc instead of importing the methods from io.rest-assured.RestAssured and io.rest-assured.matcher.RestAssuredMatchers:


Spring MVC를 사용한다면, Spring-mock-mvc 모듈을 사용하여 Rest Assured DSL을 사용하여 Spring Controllers를 테스트 할 수있다. 이렇게하려면 io.rest-assured.RestAssured 및 io.rest-assured.matcher.RestAssuredMatchers에서 메서드를 가져 오는 대신 RestAssuredMockMvc에서 메서드를 정적으로 가져옵니다.


io.restassured.module.mockmvc.RestAssuredMockMvc.*
io.restassured.matcher.RestAssuredMatchers.*


Version 2.x


If you need to depend on an older version replace groupId io.rest-assured with com.jayway.restassured.


이전 버전에 의존해야한다면 com.jayway.restassured로 groupId io.rest-assured를 교체하십시오.


Documentation


When you've successfully downloaded and configured REST Assured in your classpath please refer to the usage guide for examples.


클래스 패스에 REST Assured를 성공적으로 다운로드하고 구성한 경우 예제를 보려면 사용 설명서를 참조하십시오.






Usage Guide




Note that if you're using version 1.9.0 or earlier please refer to the legacy documentation.


버전 1.9.0 이전 버전을 사용하는 경우 기존 설명서를 참조하십시오.


REST Assured is a Java DSL for simplifying testing of REST based services built on top of HTTP Builder. It supports POST, GET, PUT, DELETE, OPTIONS, PATCH and HEAD requests and can be used to validate and verify the response of these requests.


REST Assured는 HTTP 빌더 위에 구축 된 REST 기반 서비스의 테스트를 단순화하기위한 Java DSL입니다. POST, GET, PUT, DELETE, OPTIONS, PATCH 및 HEAD 요청을 지원하며 이러한 요청의 응답을 확인하고 검증하는 데 사용할 수 있습니다.




Contents

  1. Static imports
  2. Examples
  3. JSON Example
  4. JSON Schema Validation
  5. XML Example
  6. Advanced
  7. XML
  8. JSON
  9. Additional Examples
  10. Note on floats and doubles
  11. Note on syntax (syntactic sugar)
  12. Getting Response Data
  13. Extracting values from the Response after validation
  14. JSON (using JsonPath)
  15. XML (using XmlPath)
  16. Single Path
  17. Headers, cookies, status etc
  18. Multi-value headers
  19. Multi-value cookies
  20. Detailed Cookies
  21. Specifying Request Data
  22. Invoking HTTP resources
  23. Parameters
  24. Multi-value Parameter
  25. No-value Parameter
  26. Path Parameters
  27. Cookies
  28. Headers
  29. Content-Type
  30. Request Body
  31. Verifying Response Data
  32. Response Body
  33. Cookies
  34. Status
  35. Headers
  36. Content-Type
  37. Full body/content matching
  38. Use the response to verify other parts of the response
  39. Measuring response time
  40. Authentication
  41. Basic
  42. Preemptive
  43. Challenged
  44. Digest
  45. Form
  46. CSRF
  47. OAuth
  48. OAuth1
  49. OAuth2
  50. Multi-part form data
  51. Object Mapping
  52. Serialization
  53. Content-Type based Serialization
  54. Create JSON from a HashMap
  55. Using an Explicit Serializer
  56. Deserialization
  57. Content-Type based Deserialization
  58. Custom Content-Type Deserialization
  59. Using an Explicit Deserializer
  60. Configuration
  61. Custom
  62. Parsers
  63. Custom
  64. Default
  65. Default Values
  66. Specification Re-use
  67. Filters
  68. Ordered Filters
  69. Response Builder
  70. Logging
  71. Request Logging
  72. Response Logging
  73. Log if validation fails
  74. Root Path
  75. Path Arguments
  76. Session Support
  77. Session Filter
  78. SSL
  79. SSL invalid hostname
  80. URL Encoding
  81. Proxy Configuration
  82. Static Proxy Configuration
  83. Request Specification Proxy Configuration
  84. Detailed configuration
  85. Encoder Config
  86. Decoder Config
  87. Session Config
  88. Redirect DSL
  89. Connection Config
  90. JSON Config
  91. HTTP Client Config
  92. SSL Config
  93. Param Config
  94. Spring Mock Mvc Module
  95. Bootstrapping RestAssuredMockMvc
  96. Asynchronous Requests
  97. Adding Request Post Processors
  98. Adding Result Handlers
  99. Using Result Matchers
  100. Interceptors
  101. Specifications
  102. Resetting RestAssuredMockMvc
  103. Spring MVC Authentication
    1. Using Spring Security Test
    2. Injecting a User
  104. Note on parameters
  105. Scala Support Module
  106. Kotlin
  107. More Info



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



README.md


Protractor-Perf


Just like Protractor is the end to end test case runner for AngularJS to check for functional regressions, this project is a way check for performance regressions while reusing the same test cases.


Protractor가 기능적 회귀 (functional regressions) 를 검사하는 end to end test case runner 인 것처럼,  이 프로젝트는 동일한 테스트 케이스를 재사용하면서 performance regressions를 확인하는 방법입니다.




Usage


Install protractor-perf using npm install -g protractor-perf.


npm install -g protractor-perf를 사용해 protractor-perf 를 설치하세요.


Protractor test cases are re-used to run scenarios where performance needs to be measured. Protractor-perf can be used just like protractor, just that the test-cases need to be instrumented to indicated when to start and stop measuring performance.


Protractor 테스트 케이스는 performance을 측정해야하는 시나리오를 실행하기 위해 재사용됩니다. Protractor-perf는 Protractor처럼 사용할 수 있습니다. performance를 측정하기 위해 시작점과 끝나는 지점을 테스트 케이스 내에 정해주고 난 후 측정할 수 있습니다 


Protractor is usually invoked using $ protractor conf.js. Use $ protractor-perf conf.js instead to start measuring performance.


Protractor는 일반적으로 $ protractor conf.js.를 사용하여 호출됩니다. $ protractor-perf conf.js를 사용하여 성능 측정을 시작하십시오.



The config file is the same configuration file used for protractor tests.


config 파일은 Protractor 테스트에 사용되는 것과 동일한 구성 파일입니다.



Note: If you run selenium using protractor's webdriver-manager, you would need to specify seleniumPort and selenium keys in the config file, to explicitly specify the port on which the selenium server will run. This port will also be picked up by protractor-perf. See ./test/conf.js as an example.


참고 : Protractor의 webdriver-manager를 사용하여 selenium을 실행하는 경우 seleniumPort와 selenium keys를 config 파일에 명시합니다. 이렇게 함으로서 셀레니엄 서버가 돌아갈 포트를 특정할 수 있습니다.  ./test/conf.js 의 예를 참조하십시오.


When the instrumented test cases are run using protractor, the code related to performance is a no-op. This way, adding instrumentation does not break your ability to run protractor to just test for functionality.


퍼포먼스 테스팅이 구현 된 테스트 케이스가 Protractor를 사용하여 실행될 때 성능과 관련된 코드는 작동하지 않습니다. 이런 방법으로 이 기능을 추가해도 Protractor를 작동시켜 functionalityㄹ으 테스트하는 기능은 영향을 받지 않습니다.




Instrumenting the test cases

The test case need to specify when to start and stop measuring performance metrics for a certain scenario. The following code is an example of a test case, with perf code snippets added.


테스트 케이스에 특정 시나리오에 대한 performance metrics 측정을 시작하고 중지 할 시기를 지정합니다. 다음 코드는 perf 코드 snippets이 추가 된 테스트 사례의 예입니다.


var PerfRunner = require('..');
describe('angularjs homepage todo list', function() {
	var perfRunner = new PerfRunner(protractor, browser);

	it('should add a todo', function() {
		browser.get('http://www.angularjs.org');
		perfRunner.start();

		element(by.model('todoList.todoText')).sendKeys('write a protractor test');
		element(by.css('[value="add"]')).click();

		perfRunner.stop();

		if (perfRunner.isEnabled) {
			expect(perfRunner.getStats('meanFrameTime')).toBeLessThan(60);
		};

		var todoList = element.all(by.repeater('todo in todoList.todos'));
		expect(todoList.count()).toEqual(3);
		expect(todoList.get(2).getText()).toEqual('write a protractor test');

	});
});


The four statements to note are

메모 할 4 가지 문구는 다음과 같습니다.


  1. Initialize the Perf monitor using new ProtractorPerf(protractor, browser)
  2. To start measuring the perf, use perf.start()
  3. Once the scenario that you would like to perf test completes, use perf.stop()
  4. Finally, use perf.getStats('statName') in expect statements to ensure that all the performance metrics are within the acceptable range.

The perf.isEnabled is needed to ensure that perf metrics are not tested when the test case is run using protractor directly.


1. new ProtractorPerf (Protractor, browser)를 사용하여 Perf 모니터를 초기화하십시오.

2. perf를 측정하려면 perf.start ()를 사용하십시오.

3. perf 테스트를 수행하려는 시나리오가 완료되면 perf.stop () 를 사용하십시오.

4. 마지막으로 expect 문에서 perf.getStats ( 'statName')를 사용하여 모든 performance metrics이 허용되는 범위 내에 있는지 확인하십시오.


perf.isEnabled는 Protractor를 사용하여 테스트 케이스를 직접 실행할 때 perf metrics을 테스트하지 않도록하기 위해 필요합니다.



Metrics measured


protractor-perf is based on browser-perfbrowser-perf measures the metrics that can be tested for regressions. Look at browser-perf's wiki page for more information about the project.


protractor-perf는 browser-perf를 기반으로합니다. browser-perf는 regressions 테스트 할 수있는 metrics을 측정합니다. 프로젝트에 대한 자세한 내용은 browser-perf의 wiki 페이지를 참조하십시오.




Grunt Integration


Invoke protractor-perf from a GruntFile as below


아래와 같이 GruntFile 에서 protractor-perf를 Invoke 시키세요.


module.exports = function(grunt) {
  var protractorperf = require('protractor-perf');
  grunt.registerTask('protractorperf', function() {
    var donerun = this.async();
    // Optional config Object that overwrites properties of conf.js.
    // Useful to set property values from grunt.option()
    var argv = {
      selenium: 'http://localhost:54321/wd/hub',
      seleniumPort: 54321
    };
    protractorperf.run('./merci-perf-conf.js', donerun, argv); // config file
  });
  grunt.registerTask('run', ['protractorperf']);
};



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

티스토리 툴바