속도와 종류에 따라 테스트 계획 세우기

테스트를 실행하고 실행시간을 측정해 보면 테스트들을 단위테스트와 통합 테스트로 분류할 수 있다. 폴더나 네임스페이스만으로 구분해도 충분히다.

테스트가 실패의 몇 가지 이유

  1. 테스트 대상 코드에 버그가 존재한다.
  2. 테스트가 작성된 방식에 문제가 있다
  3. 테스트가 이제는 적절하지 않다.
  4. 실행하는 데 설정이 필요하다

통합 테스트가 테스트 프로젝트 안에서 단위 테스트와 섞여 있는 것은 좋지 않다. 통합 테스트와 단위 테스트를 별개 장소로 두어야 한다. 그렇게 함으로써  최신 버전의 소스코드를 받아 특정한 네임스페이스나 폴더에 들어 있는 모든 테스트를 실행하면 모두 녹색 불이 켜지는 곳이어야 한다.

테스트는 소스 컨트롤의 일부여야 한다. 테스트 코드는 실제 제품코드와 마찬가지로 소스 컨트롤 저장소에 들어 있어야 한다. 제품의 각 버전을 담는 가지(branch)안에 트세트도 포함 되어야 하고, 개발자가 최신 버전을 내려받을 때 자동으로 함께 내려받을 수 있어야 한다. 테스트는 대산 코드 및 API와 긴밀하게 엮어 있기 때문에 테스트 대상코드 버전에 붙어서 따라다녀야 한다. 제품의 버전 1.0.1를 가져오면 제품에 대한 테스트 버전 1.0.1도 딸려 와야 한다.

테스트 클래스를 만들 때 다음과 같은 일들을 쉽게 할 수 있도록 조직해야 한다.

  1. 프로젝트를 보고 관련된 모든 테스트 찾기
  2. 클래스를 보고 관련된 모든 테스트 찾기
  3. 메서드를 보고 관련된 모든 테스트 찾기

 

자동화된 빌드에서 자동화된 테스트 실행

요구사항에 대한 변경 요청이 들어왔을 때 다음 절차

  1. 코드를 조금 수정한다.
  2. 기존 기능을 망가뜨리지 않았는지 확인하기 위해 모든 테스트를 실행한다.
  3. 수정된 부분이 다른 부분과 잘 통합되는지 확인해서 수정된 부분에 의존하는 다른 프로젝트들이 잘 돌아가는지 확인한다.

코드 통합을 위해 다음 절차

  1. 최신 버전의 소스코드를 소스코드 저장소에서 받아온다
  2. 전체를 로컬 머신에서 컴파일을 시도해 본다.
  3. 로컬 머신에서 모든 테스를 실행한다.
  4. 망가진 것이 있으면 고친다.
  5. 소스코드를 체크인한다.

자동화된 빌드

  1. 모든 프로젝트의 최신 버전을 가져온다.
  2. 모든 프로젝트를 최신 버전으로 컴파일한다.
  3. 빌드 출력물을 테스트 서버에 배포한다.
  4. 로컬 머신이나 테스트 서버에서 테스트를 실행한다.
  5. 날짜와 빌드 번호를 기반으로 해서 빌드 출력물들을 보관해 둔다.
  6. 출력물을 스테이징 서버에 배포하거나 심지어는 제품 서버에 배포한다.
  7. 대상 서버에서 컴포넌트를 설정하고 설치한다.
  8. 이 단계 가운데 하나라도 실패하면 관련 있는 사람들에게 알린다. (이메일로)
  9. 데이터베이스들을 통합한다.
  10. 빌드 품질, 이력, 테스트 상황에 대한 보고서를 생성한다.
  11. 특정 과업이 실패할 경우 과업 또는 작업 아이템을 자동으로 생성한다.(팀 시스템) 작업이 아이템을 추가한다거나 해서).

자동화된 빌드 종류

  1. 야간 빌드(nightly build)
    1. 오래 걸리는 테스트를 전부 실행한다.
    2. 시스템 테스트를 실행한다.
  2. 릴리즈 빌드(release build)
    1. 야간 빌드를 실행한다.
    2. 서버에 배포하고 결과물을 보관해둔다
  3. 지속적인 통합(CI) 빌드
    1. 금방 끝나는 테스트를 전부 실행한다.
    2. 10분 안에 끝난다.

테스트를 작성하는 과정에서 테스트들을 실행시간에 따라 분류하는 것이 좋다.

  1. 금방 끝나는(fast-running) 테스트
  2. 오래 걸리는(slow-running) 테스트

테스트가 실패의 몇 가지 이유

  1. 테스트 대상 코드에 버그가 존재한다.
  2. 테스트가 작성된 방식에 문제가 있다
  3. 테스트가 이제는 적절하지 않다.
  4. 실행하는 데 설정이 필요하다

 

 

The Art of Software Testing

82008774_117702023082154_317269272810225664_o

테스팅은 에러를 찾기 위해 프로그램을 실행하는 프로세스다.

프로그램 테스트도 환잔 검진처럼 생각해야 한다.

프로그램 테스팅이 프로그램 안의 드러나지 않은 에러를 찾는 과정이라고 한다면, 프로그램 테스팅은 가능한 작업이다.

테스팅은 프로그램이 의도한 작업을 하는지 그 여부를 시연하는 과정이라는 정의는 프로그램 내부에 에러는 있지만, 프로그램이 해야 하는 작업을 실행함을 의미한다.

블랙박스 테스팅 : 프로그램 명세대로 그 프로그램이 작동하지 않는 상황을 발견하는데 집중한다.

하이트박스 테스팅 : 프로그램의 내부 구조를 조사하는 화이트박스 또는 논리 주도 테스팅이 있다. 이 전략에는 두가지 문제, 프로그램내 로직 경로의 수가 천문학적이라는 것과 철저한 경로 테스팅은 완전한 테스트를 의미한다는 말에 의거에 모든 경로를 테스트 할 수 있다손 치더라도 그 프로그램은 에러가 발생할 수 있다는 것이다. 1. 철저한 경로 테스트가 프로그램의 사양과 일치함을 보장하지 않는다. 2. 누락된 경로 때문에 프로그램이 잘못될 수 있다. 3. 철저한 경로 테스팅으로 데이터 민감성 에러를 발견할 수 없다.

소프트웨어 테스팅 원칙

  1. 테스트 케이스의 필요한 부분은 예상 출력이나 결과에 대한 정의다.
    1. 프로그램의 입력 데이터에 대한 기술
    2. 입력 데이터에 대한 프로그램의 정확한 출력에 대한 기술
  2. 프로그래머는 자시의 프로그램 테스트를 피해야 한다.
    1. 다른 사람이 테스팅하면 더 효과적이고 성공적이다.
  3. 프로그래밍 조직은 자신들의 프로그램을 테스트하지 말아야 한다.
    1. 제3자가 목표에 따라 테스팅하는 것이 보다 경제적이라는 말이다.
  4. 테스트 결과를 철저하게 조사해야 한다.
  5. 유효하고예상 가능한 입력 조건에 대한 테스트 케이스 작성은 물론, 예상치 못한 무효한 입력조건에 대해서도 테스트 케이스를 작성해야 한다.
  6. 프로그램이 해야 할 것을 하지 않는 지에 대한 조사도 중요하지만, 프로그램이 하지 말아야 할 것까지 하는지도 찾아내야 한다.
  7. 한번 사용하고 버리는 프로그램이 아니라면, 사용하고 버리는 테스트 케이스를 만들어서는 안 된다.
  8. 에러를 발견하지 못할 것이라는 암묵적인 합의 하에 테스트 수행 계획을 작성하면 안 된다.
  9. 프로그램의 한 섹션에 많은 에러가 있을 가능성은 그 섹션에서 발견된 에러 수에 비례한다.
  10. 테스팅은 극도로 창의적이고 지적인 도전이다.

요약 :

  • 테스팅은 에러를 찾기 위해 프로그램을 실행하는 프로세스다
  • 발견 못한 에러를 찾을 확률이 높아야 좋은 테스트 케이스다
  • 성공적인 테스트 케이스는 발견하지 못한 에러를 찾는 테스트 케이스다

우리는 어떻게 일하는가?

  • 진정성(Integrity)
    • 회사의 성장을 공동의 목적으로 인식하고 이를 위해 노력하고 있습니까?
    • 회사가 시장에 공급하는 가치에 대해서 이해하며 고민하고 있습니까?
    • 업무 및 기타 비용/사무처리에 있어서 회사의 이익과 효율성을 우선에 두고 있습니까?
    • 항상 스스로의 능력의 100%를 발휘하고 있습니까?
    • 의존적이지 않고 능동적으로 일하고 있습니까?
    • 자신이 맡은 일에 있어서 최선의 완성도를 추구하고 있습니까?
    • 회사와 부서가 같이 책임져야 하는 공동의 삶의 공간이라는 주인의식을 가지고 있습니까?

  • 효율성(Efficiency)
    • 합리적이고 효율적으로 일하고 있습니까?
    • 자기입장에서의 효율성이 아닌 팀과 부서, 회사 차원의 효율성을 우선하고 있습니까?
    • 의사소통과 협업을 중심에 두고 일하고 있습니까?
    • 상대방과의 공감(Empathy)을 토대로 의사소통하고 있습니까?

  • 창의성(Creativity)
    • 맥락과 문제의식, 상황을 이해하며 생각하며 일하고 있습니까?
    • 문제를 현실의 이유로 보지 않고 극복해야할 대상으로 보고 있습니까?
    • 요구되는 변화와 학습을 진정성 있게 받아들이고 실천하고 있습니까?

 

  • 업무 관련
    • SW와 컴퓨터 동작 원리에 대한 이해
      : 개발 언어를 효율적으로 구사하고 새로운 개발 언어를 빠르게 습득할 수 있도록, SW 동작 원리와 컴퓨터의 동작 원리를 깊게 이해하고자 노력하고 있습니까?
    • DevOps 시스템 자동화 역량
      : 빌드 및 테스트, 배포와 관련된 업무 중, 사람이 반복적으로 수행하고 있는 업무를 자동화된 시스템으로 대체시키고 있습니까?
    • DevOps 시스템 효율성 증대 역량
      : 기존에 자동화된 시스템의 효율(동작시간)을 단축하기 위해서 댜양한 시도를 하고 있습니까?
      : 효율성을 높이기 위해서 변화하는 DevOps 트렌드를 검토하고 반영하기 위해서 노력하고 있습니까?
  • 사업 관련
    • 시장 요구사항에 대한 이해
      : AC 시스템의 구성요소인 Reader, Door, Elevator, Access Group, Area(Zone)와 이와관련된 기본 요구사항에 대해서 이해하고 있는가?  
    • 시장에서 사용되는 기술에 대한 개념, 동향 이해
      : AC 시장 및 Bio-metric 시장에서 사용되는 Wiegand, OSDP, RF Card, FAR, FRR, Bio-metric Template Data 등에 대해서 개념 및 활용방식에 대해서 이해하고 있는가?
      : AC 시장에서 새롭게 부각되는 기술(OSDP, 13.56Mhz 스마트카드, …)과 사라지는 기술(Wiegand, 125Khz RF 카드, …)에 대한 정보와 그 이유를 알고 있는가?

 

개발 관련

  • 개발 언어 및 SW 동작 메카니즘에 대한 이해
  • Sprint Planning 역량
  • Test Case 도출 역량
  • Test(Unit Test, API Test, UI Test) 구분 및 구현 역량
  • Code Review 역량

 

사업 관련

    • 목표시장, 주변시장, 목표시장과 주변시장의 관계에 대한 이해
    • 시장 요구사항에 대한 이해
    • 시장 요구사항의 흐름 파악
    • 시장에서 사용되는 기술에 대한 개념, 동향 이해
  • Sprint Planning
    • 구현해야 하는 요구사항을 이해하기 위해서 사용자의 입장에서 깊게 고민하고 있는가?
    • 실질적인 의사소통을 기반으로 각 요구사항의 개발 및 검증에 참여하는 모두의 고민과 생각에 기반해서 계획(예상 일정과 Story Point)이 수립되는가?
    • Security, Usability, Performance, Stability를 고려하여 계획을 수립하고 있는가? 
    • 실질적인 계획(예상 일정과 Story Point)이 수립되는가?
        
  • Creating Test Case
    • 해당 기능을 사용하며 발생할 수 있는 모든 경우를 포함시키기 위해서 노력하고 있는가?
    • Security, Usability, Performance, Stability를 고려하여 Test Case를 만들고 있는가?
    • 각 Test Case는 실제 동작을 오해 없이 설명할 수 있을 정도로 구체화되고 있는가?
    • 각 Test Case는 성공과 실패 경우를 포함하고 있는가?
  • Implementing Test Case
    • Unit Test, API Test, UI Test, Manual Test를 통해서 마련되 모든 테스트 케이스가 구현 및 확인될 수 있도록 관리하고 있는가?
    • Unit Test, API Test, UI Test, Manual Test 중에 해당 테스트 케이스를 가장 효율적으로 구현할 수 있는 방법을 선택하고 있는가?
    • Manual Test의 비중을 줄이기 위해서 노력하고 있는가?
    • Unit Test Code, API Test Code, UI Test Code 작성 시에 Test Case의 모든 내용을 포함하며 Test 수행 시간을 줄이기 위해서 노력하고 있는가?
  • Implementing Source Code & Adjusting Test Case

    • Unit Test, API Test, UI Test의 경우 Test Code를 먼저 작성한 후에 Source Code 작성을 시작하고 있는가?
    • 개발 및 검증 과정에서 Test Case 내용과 Test Code에 대한 반복적인 리뷰와 보완이 진행되고 있는가?
    • Security, Usability, Performance, Stability를 고려하여 Source Code를 작성하고 있는가?
    • Source Code 작성 후 Git 서버에 Merge하기 전에 팀(스크럼) 내에서 Source Code에 대한 리뷰가 진행되는가? 
    • Unit Test, API Test, UI Test를 통해서 Source Code에 대한 Test Coverage 100%를 만족시키기 위해서 노력하고 있는가?
    • 검증된 Unit Test Code, API Test Code, UI Test Code가 CI 환경에서 지속적으로 동작할 수 있도록 관리하고 있는가?

#200102

safe_image

DevOps

  • 개발과 운영이 분리되면서 오는 문제점을 해결하기 위해서, 개발과 운영을 하나의 조직으로 합쳐서 팀을 운영하는 문화이자 방법론
  • 엔지니어가, 프로그래밍하고, 빌드하고, 직접 시스템에 배포 및 서비스를 RUN한다. 그리고, 사용자와 끊임 없이 Interaction하면서 서비스를 개선해 나가는 일련의 과정이자 문화
  • Flicker의 경우에는 하루에 10번 정도 [1]Deploy를 한다고 한다. 일반적인 인터넷 서비스가 한달에 한번 업데이트 빨라야 일주에 한번인데, 하루에 10번이라면, 경쟁 구조 자체가 틀려진다.
  • PuppetLab (Configuration management 자동화 툴)의 블로그[2]에 따르면 DevOps를 적용 할 경우,경쟁사에 비해서 30배 정도 더 자주 Deployment를 할 수 있으며, Deployment 실패 비율도 50% 이상이나 줄일 수 있다는 것이다
  • 하나의 팀에 각각 다른 역할을 할 수 있는 팀원들로 셋업해서 전체 End 2 End 서비스를 운용할 수 있도록 한다. 앞에서 개발자가 만능이 돼야 한다고 이야기했지만, 그렇다고 만능 개발자로 전체 팀을 채워서 일하라는 것이 아니다. 개발자의 커버러지가 넓어지고 협업은 해야 하겠지만, 그렇다고 모든 개발자가 그렇게 수퍼 개발자일 리는 없고, 엄연하게 다른 역할이 존재한다. 예를 들어, 테스트 엔지니어, 빌드엔지니어 등. 단 여기서 Cross functional team이란, 한 팀 내에서 서비스의 기획에서부터 운영 그리고 더 나아가서 영업 등 해당 서비스에 관련된 모든 것 “ALL!!”을 할 수 있는 구조로 팀을 셋업 하라는 것이다.
  • 개인적으로 가장 중요하다고 생각하는 항목 중의 하나인데, 팀 전체가 기준으로 삼을 수 있는 서비스에 대한 공통적인 지표 (Metric)이 필요하다. 서비스를 개발하고 개선했을 때, 이를 평가하고 현재의 서비스 진행 상태 (성공 여부, 시스템의 안정성, 사용자의 반응 등)를 인지할 수 있는 기준이 필요하다는 것이다.예를 들어, 일 방문자 수, 평균 체류 시간, 가입자 수와 같은 비즈니스 지표에서부터, CPU 사용률, 메모리 사용률, 응답 시간 등 기술 지표 등이 있다.기존 개발에서는 요건 받아서 개발하고, 운영으로 던져버렸기 때문에, 사용자들이 서비스에 만족하는지 운영에는 문제가 없는지에 대한 피드백이 전혀 없었다. 이 Metric을 팀 전체에 공유하고 꾸준하게 추적함으로써, 팀 전체가 서비스의 상태를 인지하고, 협업을 통해서 이에 대한 개선 작업을 진행할 수 있게 되는 것이다.※ 대형 TV나 모니터 등으로, 기본 서비스 및 시스템 운영 지표에 대해서는 사무실에 붙여 놓는 것도, 나쁘지 않다
  • 반복적인 작업을 툴을 이용해서 자동화한다. 일반적으로 우리가 CI (Continuous Integration)이나 CD (Continuous Delivery) 등을 이용해서 다루는 빌드, 배포, 테스트 자동화 들이 이에 속한다. 반복적인 작업의 자동화를 통해서 똑똑한 개발 자원들이 반복작업에 투여되는 시간을 줄여서 작업의 효율을 높이고 여기에 더해서 배포나 테스트에 관련된 시간을 줄여서 빠른 서비스 업데이트를 가능하게 하며, 마지막으로 이런 자동화 시스템 구축을 통해서 전체 시스템에 대한 이해도를 높일 수 있다.
  • 사후 검증 정도의 의미가 되는데, 장애나 이슈가 있을때, 처리 후에, 그 내용을 전체 팀과 공유해야 한다. 서비스를 운영하는 팀의 문제점은 이슈등에 대한 심각도가 얼마나 높은지를 인지하지 못하는 경우가 많다. 시스템이 정지되었을 때, 비즈니스 적으로 손실이 어떤지,얼마나 심각한 문제를 인지하고 궁극적으로는 원인을 파악함으로써 다음 부터는 같은 이슈가 다시 발생하지 않도록 할 수 있다.
  • 마지막으로 정기 릴리즈이다. 시스템 릴리즈는 많은 협업이 필요한 작업이다. 개발도 끝내야 하고, 테스트, 배포 과정을 거쳐야 하고, 릴리즈가 끝나면 다음 릴리즈를 위한 기능 정의 등의 과정을 거쳐야 한다. 그래서 정기적으로 릴리즈 주기를 설정하면, 전체 협업을 하는 입장에서 언제 어떤 협업을 해야 할지도 명확해지고, 개발이 리듬(?)을 타게 된다.첨언을 하자면, 짧은 주기의 정기 릴리즈를 통해서, 빠르게 서비스의 기능을 개선하고, 고객의 VoC를 반영해나갈 수 있다.

멈추지 못하는 사람들

76904498_553955142064318_2009611100399599616_o

저자 : 애덤 알터, 페이지: 385p

저자는 행위 중독에 관여하는 요소는 모두 여섯 가지라고 말을 합니다.

  1. 손에 잡힐 듯 말 듯한 목표
  2. 뿌리치기 어렵고 예측 불가능한 긍정적인 피드백
  3. 조금씩 향상되고 있다는 느낌,
  4. 시간이 지날수록 서서히 더 어려워지는 과제,
  5. 해소하고 싶지만 풀리지 않는 미결 상태
  6. 강한 인간관계

종류는 다양하지만,  페이스북, 인스타그램 사용자는 더 많은 사람들이 ‘좋아요’를 누를 만한 사진을 끊임없이 올리거나,  수시로 인스타그램을 검색을 합니다. 또, 게이머들은 특정한 게임을 며칠씩 계속해서 미션을 완수하도록 독려받고 다른 게이머들과 하나로 묶어 주는 강한 유대관계를 형성하기도 합니다.

이런 형상은 얼마 되지는 않았지만, 벌써 위기의 징후가 나타나고 있으며, 중독이 해로운 것은 일과 놀이, 기본적인 건강, 다양한 사회적 교류 등 다른 중요한 목표를 추구할 수 없게 만들기 때문이라고 저자는 말을 하고 있습니다.

그렇다면 해결할 수 있는 대안은 존재를 하고 있는지, 해로운 중독을 퇴치하는 동시에 그것을 유익한 방향으로 활용할 수 있는 길이 있는지를 이 책에서 한번 알아 볼 수  있습니다.

conflunce & curl

import requests
import json
import base64# Set the confluence User and Password for authentication
user = ‘xxxxx’
password = ‘xxxxx’# Set the title and content of the page to create
page_title = ‘My New Page’
page_html = ‘<p>This page was created!</p>’# You need to know the parent page id and space key.
# You can use the /content API to search for these values.
# Parent Page example http://example.com/display/ABC/Cheese
# Search example: http://example.com/rest/api/content?title=Cheese
parent_page_id = xxxxx
space_key = ‘xxxxx’# Request URL – API for creating a new page as a child of another page
url = ‘http://xx.xx.x.xx:xxxx/rest/api/content/‘# Create the basic auth for use in the authentication header
#auth = base64.b64encode(b'{}:{}’.format(user, password))
#auth = base64.b64encode(b'{%s}:{%s}’ % (user, password))
auth_str = ‘%s:%s’ % (user, password)
#b64_auth_str = base64.b64encode(auth_str.encode(‘utf-8′))
#print(b64_auth_str)#’Authorization’: ‘Basic {}’.format(b64_auth_str),
# Request Headers
headers = {
  ‘Authorization’: ‘%s’ % auth_str,
  ‘Content-Type’: ‘application/json’,
}# Request body
data = {
  ‘type’: ‘page’,
  ‘title’: page_title,
  ‘ancestors’: [{‘id’:parent_page_id}],
  ‘space’: {‘key’:space_key},
  ‘body’: {
      ‘storage’:{
          ‘value’: page_html,
          ‘representation’:’storage’,
      }
  }
}# We’re ready to call the api
try:   r = requests.post(url=url, data=json.dumps(data), headers=headers)   # Consider any status other than 2xx an error
  if not r.status_code // 100 == 2:
      print(“Error: Unexpected response {}”.format(r))
  else:
      print(‘Page Created!’)except requests.exceptions.RequestException as e:   # A serious problem happened, like an SSLError or InvalidURL
  print(“Error: {}”.format(e))

[API] node Test

‘use strict’;
let getIPAddress = function ()
{
var interfaces = require(‘os’).networkInterfaces();
for (var devName in interfaces) {
var iface = interfaces[devName];

for (var i = 0; i < iface.length; i++) {
var alias = iface[i];
if (alias.family === ‘IPv4’ && alias.address !== ‘127.0.0.1’ && !alias.internal)
return alias.address;
}
}
return ‘0.0.0.0’;
};
module.exports.getIPAddress = getIPAddress;

console.log(getIPAddress());

위의 구문을 파일로 만든다. node_test.js로 만든다.

node_module 폴더가 있는 디렉토리에 node_test.js을 복사를 해둔다. (node_module은 npm Install을 해서 만들어진 폴더)–>이건 기본적으로 알아야 한다.

그리고, cmd로 그 경로로 가서 실행을 한다.

경로>node node_test.js 엔터를 치면

192.168.x.x 가 나온다.