2018년 8월 27일 월요일

TestNG에서 2개 이상의 assert를 한꺼번에 처리하는 방법

개요

"@Test" 메소드에서 테스트 할 때 부득이하게 assert를 여러 번 해야 할 경우가 있다.
이 때 한꺼번에 처리해주지 않으면 첫번 째 assert에서 fail이 발생할 경우, 그 아래에 있는 assert 구문을 처리하지 않고 테스트가 종료되어 남아있는 assert 구문을 확인할 수 없다.
이를 해결하기 위한 방법을 정리한다.

내용

TestNG에서는 Hard assert / Soft Assert로 구분한다.
Hard Assert는 assert 시 fail이 발생하면 해당 테스트를 종료하는 것이고,
Soft assert는 assert 시 fail이 발생해도 로그에서는 fail이지만 테스트 결과는 pass로 해준다. 최종 결과를 확인하기 위해서는 아래와 같이 사용해야 한다.

Hard Assert


@Test
public void hardAssertTest(){
   Assert.assertFalse(2<1);
   System.out.println("Assertion Failed in Test 1");
   Assert.assertTrue(1<0);
   System.out.println("Assertion Failed in Test 2");
   Assert.assertEquals("Sample", "Sample");
   System.out.println("Assertion Passed in Test 3");
}
결과
Assertion Failed in Test 1
FAILED: hardAssertTest1
java.lang.AssertionError: expected [true] but found [false]
at org.testng.Assert.fail(Assert.java:94)
at org.testng.Assert.failNotEquals(Assert.java:513)
at org.testng.Assert.assertTrue(Assert.java:42)
at org.testng.Assert.assertTrue(Assert.java:52)
at testng.TestNGTest2.hardAssertTest1(TestNGTest2.java:13)
...
3번 line : PASS, 5번 line : FAIL이 발생하여 7번line의 assert를 하지 않고 hardAssertTest()의 테스트를 종료하고 빠져나온다. 테스트의 최종결과는 FAIL

Soft Assert 1


@Test
public void softAssertTest1(){
   SoftAssert sa= new SoftAssert();
   sa.assertTrue(2<1);
   System.out.println("Assertion Failed1");
   sa.assertFalse(1<2);
   System.out.println("Assertion Failed2");
   sa.assertEquals("Sample", "Failed");
   System.out.println("Assertion Failed3");
}
결과
Assertion Failed1
Assertion Failed2
Assertion Failed3
PASSED: softAssertTest1
assert는 fail이지만 테스트 결과는 PASS로 된다.

Soft Assert 2


@Test
public void softAssertTest2(){
   SoftAssert sa= new SoftAssert();
   sa.assertTrue(2<1);
   System.out.println("Assertion Failed1");
   sa.assertFalse(1<2);
   System.out.println("Assertion Failed2");
   sa.assertEquals("Sample", "Failed");
   System.out.println("Assertion Failed3");
   sa.assertAll();
}
결과
Assertion Failed1
Assertion Failed2
Assertion Failed3
FAILED: softAssertTest2
java.lang.AssertionError: The following asserts failed:
expected [true] but found [false],
expected [false] but found [true],
expected [Failed] but found [Sample]
at org.testng.asserts.SoftAssert.assertAll(SoftAssert.java:43)
at testng.TestNGTest2.softAssertTest2(TestNGTest2.java:54)
....
SoftAssert 객체를 생성한 후 - SoftAssert sa = new SoftAssert();
SoftAssert 객체로 assert를 모두 진행하고 난 뒤, 마지막에 "sa.assertAll()" 을 해주면 하나라도 fail이 발생 시 최종 테스트 결과는 FAIL로 된다.
assert를 모두 확인하고 테스트를 종료하므로 테스트 메소드에 assert 구문이 여러 개 일 경우 SoftAssert의 assertAll을 사용하자.

Logback 사용법

SLF4J란, Simple Logging Facade for Java의 약자로 Log4J의 개발자 Ceki Gülcü가 LogBack과 함께 개발한 Logging Facade 즉, 로깅에 대한 인터페이스 모음이라고 볼 수 있습니다.
LogBack이 바로 SLF4J의 Native 구현체이며 SLF4J를 사용하여 로깅 처리를 하면 실제 로그는 LogBack에서 출력하게 됩니다.
SLF4J에 대해 좀 더 자세히 알고 있으시면 공식 사이트(https://www.slf4j.org/) 에서 확인하세요
그리고 LogBack에 대한 메뉴얼은 https://logback.qos.ch/manual/index.html 에서 확인 가능합니다.

준비물

1.pom.xml에 logback 관련 의존성 추가

<dependencies>
   <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
      <exclusions>
         <exclusion>
            <artifactId>log4j</artifactId>
            <groupId>log4j</groupId>
         </exclusion>
         <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
         </exclusion>
         <exclusion>
            <artifactId>common-logging</artifactId>
            <groupId>common-logging</groupId>
         </exclusion>
      </exclusions>
   </dependency>
   <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>${logback.version}</version>
      <exclusions>
         <exclusion>
            <artifactId>log4j</artifactId>
            <groupId>log4j</groupId>
         </exclusion>
         <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
         </exclusion>
         <exclusion>
            <artifactId>common-logging</artifactId>
            <groupId>common-logging</groupId>
         </exclusion>
      </exclusions>
   </dependency>
</dependencies>
2. 설정파일(logback.xml) 추가
메인에 있는 코드가 실행될 때 적용하고 싶은 설정파일은  src/main/resource 밑에 두고, 테스트 단계에서 별도의 설정파일을 적용하고 싶으면 src/test/resource 밑에 둔다.
1) 로그 레벨
TRACE → DEBUG → INFO → WARN → ERROR 의 로그 레벨이 있고, 설정파일에서 설정 레벨 이상의 로그를 출력할 수 있다.
예) 레벨 : INFO로 설정하면 TRACE, DEBUG 레벨의 로그는 출력되지 않는다.

2) Appender
로그를 출력할 위치, 출력 형식등을 지정할 때 사용된다.
기본적인 Appender로는 ConsolAppender, FileAppender, RollingFileAppender가 있다.
ConsolAppender : 로그를 콘솔에 출력시킨다.
FileAppender : 로그의 내용을 지정된 파일에 기록한다.
RollingFileAppender : 지정된 패턴에 따라 로그가 파일에 기록하도록 하여 대량의 로그를 효과적으로 기록할 때 사용된다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
         <pattern>[%d{yyyy-MM-dd HH:mm:ss}] [%-5p] %C.%M[%L] %m%n</pattern>
      </encoder>
   </appender>
   <root level="debug">
      <appender-ref ref="STDOUT" />
   </root>
</configuration>
3. 코드 예

public class LogSample {
    private static final Logger logger = LoggerFactory.getLogger(LogSample.class);
    public static void main(String args[]){
  String stringMsg = "Test";
  int integerMsg = 123;
  logger.trace("trace");
  logger.debug("debug");
  logger.debug("debug {} {}", stringMsg, integerMsg);
  logger.info("info");
  logger.warn("warn");
  logger.error("error");
    }
}

결과

2016년 12월 1일 목요일

Junit MultiThread Test code


import org.junit.Test;

import junit.framework.TestCase;
import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;

public class TestThread extends TestCase{
 
 private static int THREAD_SIZE = 20;
 
 /*
  * Test class should have exactly one public zero-argument constructor이므로
  * TestCase 클래스를 extends 하고 GroboUtils의 클래스인 TestRunnable을 상속받은 클래스를 이너클래스로 사용하였다.
  */
 
 public class MultiThreadTest extends TestRunnable {
  
  private int i = 0;
  
  
  public MultiThreadTest(int i){
   this.i = i;
  }
  
  @Override
  public void runTest() throws Throwable {
   Thread.sleep(1000);
   
   System.out.println(Thread.currentThread().getName() + " : [" + i + "]");
  }
 }
 
 @Test
 public void test() throws Throwable{
  TestRunnable[] t = new TestRunnable[THREAD_SIZE];
  
  for(int index=0; index < THREAD_SIZE; index++){
   t[index]=new MultiThreadTest(index);
  }
  
  MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(t);
  mttr.runTestRunnables();
  
  System.out.println("main end.........................");
 }
}

2016년 9월 29일 목요일

Windows 환경에서 Python Selenium 설치

precodition : python3.5 설치 및 path 설정

(1) python selenium 라이브러리 설치


C:\PYTHON_HOME\..\Scripts
pip install -U selenium
실행 시 SSL 오류가 발생하였음

 Could not fetch URL https://pypi.python.org/simple/selenium/: There was a problem confirming the ssl certificate: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645) - skipping
  Could not find a version that satisfies the requirement selenium (from versions: )
No matching distribution found for selenium

[해결방안]

  1. pip upgrade(pip 버전 확인 pip --version)
  2. easy_install pyopenssl 실행
  3. pip install --upgrade --trusted-host pypi.python.org selenium








출처 : http://selenium-python.readthedocs.io/installation.html


Python if __name__ == "__main__" 정리, 설명

if __name__ == "__main__" 의미
파이썬에서 일반적으로 import 방식으로 다른 코드를 불러오는데, 파이썬이 스크립트 언어이기에 그때마다 불려온 파일에 있는 메소드와 클래스를 실행 시킨다면 원하는대로 사용하기가 힘들기에

if __name__ == "__main__" 구문을 통해 실행될 코드와 그냥 참조 대기상태로 존재할 코드를 구분할 수 있다.
__name__ 은 보통 해당 파일의 위치+이름으로 구성돼있다.
from django import db의 경우 db.__name__을 찍어보면 'django.db'가 나온다.

test.py

def say_hi():

    print("Hi")



if __name__=="__main__":

    say_hi()
test.py 파일을 python test.py 로 실행한다면 say_hi() 메소드가 실행된다. 직접 실행되는 파일의 __name__은 __main__으로 설정된다.
그러나 다른 파일에서 import test 로 위 파일을 불러온다면 say_hi()는 실행되지 않는다. 기본적으로 test.py의 __name__ 은 그냥 'test'이다. (파일명)

2016년 1월 5일 화요일

jar 파일을 자신의 로컬 레포지토리에 등록하는 방법

mvn install:install-file -Dfile=c:\kaptcha-2.3.jar -DgroupId=com.google.code -DartifactId=kaptcha -Dversion=2.3 -Dpackaging=jar

인스톨 한 후 pom.xml에 dependency 걸어주면 된다.

2015년 10월 28일 수요일

Maven에서 Dependency Version Range


Range
Meaning
1.0
"Soft" requirement on 1.0 (just a recommendation - helps select the correct version if it matches all ranges)
(,1.0]
x <= 1.0
(,1.0],[1.2,)
x <= 1.0 or x >= 1.2. Multiple sets are comma-separated
(,1.1),(1.1,)
This excludes 1.1 if it is known not to work in combination with this library
[1.0,2.0)
1.0 <= x < 2.0
[1.0]
Hard requirement on 1.0
[1.2,1.3]
1.2 <= x <= 1.3
[1.5,)
x >= 1.5