스토리 홈

인터뷰

피드

뉴스

개발에 관심있다면 꼭 읽어야하는 글
조회수 10060

Estimator: BLE를 사용한 Planning Poker 애플리케이션

1. Planning PokerStyleShare 개발팀에서는 스크럼을 활용하여 일을 진행하고 있습니다.1 스크럼에는 일감의 크기를 추정estimate하는 과정이 있는데요. 구성원들 모두가 일감에 대해 이해하고 일감의 크기가 어느정도인지 함께 논의하여 합의에 이르는 과정입니다. 스프린트 회의에서 일감을 등록한 사람(리포터)이 일감에 대해 설명하고 나서 전체 구성원들이 일감의 크기를 추정하는데, 이 때 사용하는 것이 바로 Planning Poker입니다.Planning Poker는 0.5부터 시작해서 1, 3, 5, 8, 13, 20, … 100과 같이 피보나치 수열로 증가하는 숫자를 가진 카드 덱입니다. 리포터의 설명이 끝난 뒤 스크럼 마스터가 하나, 둘, 셋을 외치면 각자 생각한 일감의 크기에 맞는 카드를 꺼내고, 스크럼 마스터는 구성원들의 추정치가 최대한 가까워지도록 부가설명이나 질문을 유도합니다.2▲ Planning Poker는 이렇게 생겼다. (출처: Control Group 블로그)하지만 개발팀이 커지면서 불편함이 생기기 시작했습니다. 회의에 참여하는 인원이 7-8명씩 되다 보니, 각자가 어떤 카드를 들고있는지 한눈에 보기가 어려워진 것입니다. StyleShare에서 자칭 아이디어 뱅크 역할을 담당하고 있는 저는 획기적인 방법이 필요하다고 생각했고, 굳이 카드를 꺼내들지 않아도 각자가 무슨 카드를 선택했는지를 쉽게 볼 수 있는 애플리케이션을 만들기로 결심했습니다.2. BLE (Bluetooth Low Energy)불편함을 덜기 위한 애플리케이션이므로, 사용자 경험이 굉장히 직관적이고 단순해야 했습니다. N:N 통신이 가능해야하고, 사용자를 귀찮게 하는 페어링Pairing이나 네트워크 접속 과정이 없어야 했습니다. 한마디로, 카드를 꺼내들고 눈으로 확인하는 것보다 더 편한 무언가를 만들어야 했습니다!처음에는 근거리 무선 통신을 위한 기술로 스타벅스에서 사이렌 오더 개발에 사용한 고주파 인식 기술을 생각했습니다.3 각자의 기기에서 선택한 카드에 맞는 소리를 내보내고, 다른 기기에서는 고주파를 읽겠다는 것이었는데요. Soundlly(구 aircast.me)와 같은 상업용 SDK를 쓰지 않는 이상, 사운드 프로그래밍을 한 번도 해본 적 없는 저에게는 데이터가 실린 고주파를 만드는 것부터 소리를 인식해서 데이터를 읽어내는 과정이 마치 화성에서 감자 키우는 이야기처럼 들렸습니다.그러다 문득 생각난 것이 바로 비콘Beacon입니다. 언젠가 소비자가 오프라인 매장에 방문하면 BLE를 이용해서 매장 위치를 파악하는 기술이 있다는 이야기를 들은 적이 있었습니다. 찾아보니 시중에 나와있는 대부분의 모바일 기기에서는 BLE를 위한 최소 조건인 블루투스 4.0을 지원했고, 페어링이나 네트워크 접속 과정도 불필요했습니다. 무엇보다, 화성에서 감자 키우는 것보다는 쉬워보였습니다.3. Swift로 BLE 개발하기그래서 BLE를 사용해서 개발하기로 했습니다. 컨셉은 간단했습니다. 내가 선택한 카드를 브로드캐스팅하고, 다른 사람들이 선택한 카드를 내 모바일 기기에 보여주면 되는 것이었습니다. BLE를 사용하면 정보를 브로드캐스팅할 수 있고, 다른 기기에서 브로드캐스팅하는 정보를 읽을 수 있습니다.BLE에서 데이터를 브로드캐스팅하는 것을 Advertising이라고 합니다. 정보를 advertising하는 주체는 Peripheral이고, advertising되는 정보를 스캔하여 데이터를 읽어들이는 주체는 Central이라고 합니다. Peripheral에서 정보를 advertising할 때에는 특정한 정보를 실어나를 수 있는데요. 이를 Advertising Data Payload라고 합니다. 이 정보에 카드 숫자와 이름을 실어서 전송하면 될 것 같습니다.BLE를 구현하기 위해서, iOS에서는 SDK에 기본적으로 포함돼있는 CoreBluetooth 프레임워크를 사용하면 손쉽게 개발이 가능합니다. CBPeripheralManager 클래스와 CBCentralManager 클래스를 쓰면 되는데요. BLE를 이용하여 제 이름 석자를 advertising하는 코드는 다음과 같습니다.Peripheralimport CoreBluetooth let serviceUUID = CBUUID(string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX") let service = CBMutableService(type: serviceUUID, primary: true) /// 1. `CBPeripheralManager`를 초기화하고, self.peripheral = CBPeripheralManager(delegate: self, queue: nil) /// 2. 사용가능한 상태가 되면 특정 UUID를 가진 서비스를 추가한 뒤에 func peripheralManagerDidUpdateState(peripheral: CBPeripheralManager) { if peripheral.state == .PoweredOn { self.peripheral.addService(service) } } /// 3. 원하는 정보를 advertising합니다. func peripheralManager(peripheral: CBPeripheralManager, didAddService service: CBService, error: NSError?) { self.peripheral.startAdvertising([ CBAdvertisementDataLocalNameKey: "전수열", CBAdvertisementDataServiceUUIDsKey: [serviceUUID], ]) } 참고로, UUID는 커맨드라인 명령어를 통해 쉽게 만들 수 있습니다.$ uuidgen XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 마찬가지로, Peripheral에서 advertising하는 정보를 스캔하는 Central 코드는 다음과 같이 작성할 수 있습니다. UUID는 Peripheral에서 advertising에 사용한 UUID와 동일해야합니다.Centralimport CoreBluetooth let serviceUUID = CBUUID(string: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX") let service = CBMutableService(type: serviceUUID, primary: true) /// 1. `CBCentralManager`를 초기화하고, self.central = CBCentralManager(delegate: self, queue: nil) /// 2. 사용가능한 상태가 되면 특정 UUID를 가진 서비스를 스캔합니다. func centralManagerDidUpdateState(central: CBCentralManager) { if central.state == .PoweredOn { // 이미 한 번 스캔된 정보라도 계속 스캔합니다. let options = [CBCentralManagerScanOptionAllowDuplicatesKey: true] self.central.scanForPeripheralsWithServices([serviceUUID], options: options) } } /// 3. Peripheral이 스캔되면 이 메서드가 호출됩니다. func centralManager(central: CBCentralManager, didDiscoverPeripheral peripheral: CBPeripheral, advertisementData: [String : AnyObject], RSSI: NSNumber) { print(advertisementData[CBAdvertisementDataLocalNameKey]) // "전수열" } 스캔을 시작할 때 CBCentralManagerScanOptionAllowDuplicatesKey 옵션을 true로 설정해서 한 번 스캔된 정보라도 중복으로 계속 스캔하도록 합니다.4. 원하는 정보를 실어나르기CBPeripheralManager을 사용하여 advertising을 할 때에는 Advertising Data Payload를 포함시킬 수 있는데, 이 정보 중 개발자가 원하는 값을 넣을 수 있는 곳은 CBAdvertisementDataLocalNameKey밖에 없습니다. 그마저도 길이가 제한돼있기 때문에, 패킷을 효율적으로 사용하기 위해서는 정보를 저장하는 프로토콜을 직접 정의해야 합니다.우선, 카드에 대한 정의는 enum을 사용해서 작성했습니다. 0부터 0xFF까지의 숫자를 가지도록 정의했습니다.public enum Card: Int { case Zero = 0 case Half = 127 case One = 1 case Two = 2 case Three = 3 case Five = 5 case Eight = 8 case Thirteen = 13 case Twenty = 20 case Fourty = 40 case Hundred = 100 case QuestionMark = 0xFD case Coffee = 0xFE case None = 0xFF } 그리고 제가 정의한 패킷의 프로토콜은 다음과 같습니다.영역길이예시설명Version200프로토콜 버전 (00~FF)Channel201BLE 커버리지 내에서 회의하는 팀이 여럿일 수 있으니, 채널로 구분합니다. (00~FF)Card2FE카드의 16진수 값 (00~FF)Name12전수열사용자 이름 (UTF-8 기준 한글 4글자)이렇게 하면 총 18바이트 내에서 필요한 정보를 모두 전송할 수 있습니다. 이제 이 "00", "01", "FE", "전수열" 값을 직렬화해서 CBAdvertisementDataLocalNameKey로 advertising하면 됩니다.Peripheralself.peripheral.startAdvertising([ CBAdvertisementDataLocalNameKey: "0001FE전수열", CBAdvertisementDataServiceUUIDsKey: [serviceUUID], ]) 그리고, Central에서 정보를 스캔할 때에는 이 값을 각 영역의 길이에 맞게 끊어서 읽을 수 있습니다.5. 마치며비록 적은 양의 정보지만, BLE를 사용해서 실시간으로 근거리 통신을 할 수 있게 되었습니다. 이제 남은 것은 카드를 선택할 수 있는 화면과, 다른 사용자가 선택한 카드를 화면에 보여주는 인터페이스입니다. UI 개발은 본 포스트에서 중점적으로 다루고자 하는 주제와는 조금 벗어난 이야기가 될 것 같아, 오픈소스로 공개된 코드로 대신하려고 합니다. 소스코드는 GitHub에서 볼 수 있으며, Estimator는 앱스토어에서 받아보실 수 있습니다.6. 참고 자료BLE(BLUETOOTH LOW ENERGY) 이해하기 - Hard Copy World스타일쉐어의 스크럼이 지나온 길 포스트에 보다 자세히 설명되어 있습니다. ↩구성원들의 추정치에 차이가 난다는 것은 해당 일감에 대해 서로가 이해하고 있는 정도가 다르기 때문입니다. 스크럼 마스터는 구성원들이 일감에 대해 모두 비슷한 생각을 가지도록 커뮤니케이션을 유도해야합니다. ↩http://www.bloter.net/archives/226643 ↩#스타일쉐어 #개발 #개발팀 #개발자 #인사이트
조회수 874

블록체인 진짜 하나도 모르는 디자이너의 독학일기(1)

독학을 시작했습니다. 스터디를 가려고 했는데 수많은 전문용어들이 제 영혼을 피폐하게 만드는 바람에 정신건강이 염려되었거든요. 포토샵도 혼자 배웠으니 이것도 못할까! 라고 자신있게 책을 폈는데 못할 것 같습니다.......그래도 산 책 값이 아까우니 읽고 공부한 내용들을 하나하나 정리해보고자 합니당! 블록체인 전문가님들이 혹시 이 글을 보신다면 노잼과 지루함내지는 유치함을 느끼실 수 있으니 엄빠미소로 지켜봐주시면 감사하겠습니다. 잘못된 부분이 있다면 바로 잡아주세요!!글을 쓰면서 5가지 원칙을 지킬겁니다.1. 꼭 써야하는 고유명사가 아닌 이상 어려운 단어는 쓰지 않습니다. 중학생 정도가 이해될 수준이길 제발 바랍니다...저는 블록체인을 이제 이틀 째 공부하고 있거든요.2. 가급적 팩트체크된 내용만 쓸겁니다.3. 제대로 공부하려면 경제사, IT기술, 코딩 등등..수많은 요소가 복잡하게 들어가지만 여기선 꼭 필요한 쏘옥 뽑아서 얘기할 겁니다. 4. 짧게 쓸 겁니다.5. 가끔 쓸 겁니다.(자주 쓰기 힘든 주제임..)시작합니당 :)블록체인이 왜 태어났는지 얜 뭔지부터 알아야 할 것 같아요. 그러자면 시간을 조금 되돌려서 우리는 어떻게 사고파는 경제활동을 해왔는지 살펴볼께요.1. 아주 오래전 = 기억하기종이란게 나타나기도 전 우리는 사과5개를 빨간집에서 해가 질 무렵에 씨앗10개와 교환했다. 는 걸 기억해야 했어요. 문제는 서로가 잘못 기억하거나 한 쪽이 다르게 우겨버리면 할 말이 없다는 거죠..철저히 신뢰와 기억에 의존한 거래였어요.2. 오래 전 = 나무나 가죽에 새기기원래 사람은 두 발로 직립보행 하기 전부터도 그림을 좋아했어요. 동굴에도 그리고 돌에도 그리고, 나무나 땅에도 곧잘 그림을 그렸죠. 뭔가 주고받는 물품이 많아지면서 기억하기가 힘들어지자, 이젠 가죽이나 나무 등등에 갯수를 남기기 시작했죠. 문제점은 그 가죽이나 나무가 훼손되거나 도난당하면 증명할 방법이 없다는 거에요.'동쪽 언덕 마을에서 온 또박이가 가죽3개를 사갔다.'3. 조금 오래전 = 종이에 적기(단식부기)종이가 발명되고 아라비아 숫자와 알파벳, 한글, 한자, 인도어 등등이 발달하기 시작하면서 문서를 남길 수 있게 되었어요!!! 문서를 남긴다는 건 굉장했죠!!!오랜 시간이 지나도 기록들을 잘 보관할 수 있었어요!! 거래를 할 때에도 수입과 지출을 한 번에 (가계부처럼) 적으면서 작은 종이에 많은 내용을 남길 수 있었답니다. 하지만..여전히 문제는 사람이었어요. 이를 위조하거나 없애버리면...? 또는 불에 다 타서 없어지면??4. 얼마 전 = 적은 걸 나눠가지기(복식부기)그래서 서로 함께 같은 내용을 공유하기로 했어요. 너 하나 나 하나. 그리고 그 과정을 감시하는 회계사. 이런 과정은 우리 조선시대에서도 아주 엄격했답니다. 특히 계문화가 발달했던 우리나라는 다양한 장부를 기록했는데 '용하기'라는 계의 장부기재는 정말 엄격한 원칙이 있었답니다!!1. 임시장부를 2부 작성해요. 이 때 회계담당자 이외 심지어 2명이 더 감시하고 있어요.2. 기재를 시작해요.3. 계원들이 다 모여야 하고 적은 내용을 크게 읽어요. 이 때 의심스러운게 있으면 이의제기나 수정을 해요.4. 계장과 두 명의 감시원이 있는 상태에서 최종수정해요. 그리고 계장이 서명해요.5. 중복된 장부가 있는지 확인하고 새 장부를 넣어 보관해요.엄청나죠???..놀라운 건 현재의 블록체인의 원리도 위와 비슷해요!! 다만 사람이 일일이 적고 감시하는 게 아니라 명령어에 의해 챡챡 처리되는 것 뿐이랄까요. 하지만 이것도 결국 '물질' 이다 보니....화재나 전쟁으로 인해 소실되어 버리면 그걸로 끝이었어요.5. 요즘 = 기관이나 중앙에 맡기기왕정체제가 아니라 민주주의와 시장경제가 도입되면서 은행이나 보험사, 카드사와 같이 경제활동을 담당하는 기업과 중앙기관이 생겨나기 시작했어요! 엄청나게 거대한 정보를 크으으은 서버나 금고에 보관할 수 있었어요. 그것은 영원해보이고 사람들은 오래도록 보관할 수 있다고 생각하니 관심을 끄기 시작했죠. 내 돈은 금고에 잘 있을 거니까요.하지만, 자본주의는 그런게 아니었어요. 은행은 내 돈을 다른 사람에게 대출로 빌려주고 그 이자로 돈을 벌어요. 그리고 다른 사람이 갚은 돈으로 다시 내 예금을 채우죠. 졸라 돌려막기인 거에요. 사람들이 끊임없이 돈을 빌리고 다시 갚을 수 있게 다양한 상품들을 만들어요. 이 방식은 굉장히 효율적이고 아무 문제가 없을 것 같이 보였어요.하지만, 해킹을 당했어요.은행을 털렸어요서브프라임 모지기론 사태처럼, 무리한 상품의 실패는 수백개의 기업을 무너뜨렸어요. 수많은 사람들의 돈이 한 순간에 날아갔어요.서버가 먹통이 되어 거래가 안되는 경우도 있어요.지진 등의 천재지변이 나면 내 기록은 사라지고 말아요.단순히 큰 사옥을 지닌 곳이니까 영원불멸할 것 같았던 중앙기관도 하루 아침에 무너질 수 있단 사실을 우린 수 차례 경험했어요. 그럼에도 우린 뭘 어떻게 해야할 지 몰랐어요. 우리가 할 수 있는 건 사고가 터지면 변호사를 써서 소송을 하는 것 뿐이었어요. 우린 은행의 상품이 정확히 어떤건지, 보험약관이 뭔지... 카드사는 어떤 원리로 움직이는지...내 세금은 어떻게 쓰이고 있는지...우리 돈이 어떻게 거래되고 내 돈을 가지고 그들이 무엇을 하는지 하나도 몰라요. 그냥 속수무책으로 그들만 믿고 있는 거예요. 6. 블록체인의 탄생 = 모두가 장부를 가질 수 있게그래서 생각해봤어요. 한 곳에 모여있으니 문제가 생긴다면, 쪼개면 되지 않을까? 은행 한 곳을 터는 것은 쉽지만 1,000여명을 한꺼번에 터는 것은 불가능할테니까. 계모임에서 쓰던 그 장부를 엄청나게 많이 만들어서 모두가 가지면 어떨까? 누굴 못 믿거나 위조하거나 털리거나 불나서 사라질 일이 없을 거 아냐?? 라는 생각을 말이죠. 그런데 친구가 질문을 하네요!!친구 : 그런데 어떻게??나 : 인터넷이 있잖아!! 내가 온라인상에서 거래하면 그 기록이 남잖아~ 그걸 모두가 공유하는거지! 친구 : 모두가 누군데?나 : 응 그건 이제부터 모아야해!!친구 : 그럼 어쨌든 모인 사람들에게 모두 공유하면 내가 어제 김치한포기 시킨것도 다른 사람이 알게 되는거야??나 : 아니지;;; 니가 뭘 시켰는지 그딴 건 관심없어..그냥 얼마 거래를 언제 몇시몇분몇초에 어떻게 했는가만 기록에 남는거야! 그리고 다른 사람은 그걸 직접 눈으로 볼 수 있는 게 아냐.생각해봐. 넌 브런치 로그인한 기록을 눈으로 다 볼 수 있어? 며칠 몇시에 얼마나 로그인했는지 알 방법이 없지? 하지만 그 기록이 있을까 없을까? 그렇지, 반드시 있다구. 범죄수사할때도 그러자나. 우리 화면에는 시간/내용밖엔 안뜨는 문자메시지지만, 실제로 서버에는 발신위치, 수신위치, 번호정보 등등이 모두 숨겨져 있잖아. 또 하나! 너가 네이버에서 틴트를 검색하면 나중에 페북에서 틴트광고가 뜨지 않아? 우리의 방문기록이나 클릭한 기록들이 모두 남아있기 때문이야.이렇게 우리가 눈으로 보는 화면 뒤에는 수많은 정보들이 컴퓨터만의 전기신호로 저장되어 있어. 우리가 말하는 장부도 이런 식으로 저장되어 있는거라구.  물론 필요하다면 그걸 화면으로 띄울 수 있는 명령어를 만들 수도 있겠지.친구 : 그건 이해했어, 내가 직접 볼 순 없지만 마치 사이트 방문기록처럼 어딘가에 거래내역이 다 남아있다는 얘기지?... 그런데 아까 지금부터 모아야 한다는 사람들은 어떻게 모으는거야??나 : 그건!!..바로!!!! 다음에 설명해줄께!!또 공부해서 돌아올께용!!
조회수 496

iOS 개발자를 구합니다!

“세상 모든 광고영상을 누구나 쉽게 만들 수 있게 한다.”영상광고는 사업의 규모와 업종을 막론하고 모든 분야에서 필수적인 요소로 자리잡고 있습니다. 잘 만든 영상광고가 매출로 이어진다는 사실은 검증되었고, 그 중요성은 나날이 증가하고 있습니다.하지만, 영상제작 전문기술 없이 광고영상을 제작한다는 것은 시간과 비용적인 측면에서 매우 어려운 일입니다. 광고영상을 SNS에 업로드 하고 싶은 마케터나 창업가들은 영상 전문가나 디자이너가 되는 것을 꿈꾸지 않습니다. 단지 자신의 서비스와 제품이 멋지게 홍보될 영상을 원하고 있습니다.더브이플래닛은 전문기술 없이도 누구나 쉽고 빠르게 광고영상을 제작할 수 있는 브이플레이트를 통해 많은 마케터들과 창업가들이 겪는 시간과 비용에 대한 어려움을 해소할 것입니다.“더브이플래닛”에서 영상광고 생태계의 흐름을 바꿀 iOS개발자를 모집합니다.광고영상을 누구나 쉽게 만들 수 있도록 함께 고민하고 시장을 주도해나갈 분을 애타게 찾고 있어요.우리는 한사람 한사람의 소중한 능력들이 맘껏 발휘될 수 있도록 존중과 배려로 서로를 응원하고 있어요. 우리와 함께 소중한 능력을 맘껏 발휘하실 분들의 많은 지원 부탁드려요.
조회수 1807

TDD(파이썬) : 테스트 잘하고 계신가요?

Overview반복적인 테스트에 지쳐가고 있던 무렵, TDD방법론을 접하게 되었습니다. TDD(Test Driven Development)는 테스트 주도적인 개발로 소스코드 작업 전에 테스트 코드를 먼저 작성해 소스수정에 대한 부담을 덜고 디버깅 시간을 줄일 수 있습니다. TDD 장점소스코드의 품질이 높다.재설계 및 디버깅 시간이 절감된다.TDD 단점단기적 코드일 경우 생산성이 떨어진다.실제 코드보다 테스트 케이스가 더 커질 수 있다.파이썬에서 TDD가 필요한 이유1) 파이썬에는 정적 타입 검사 기능이 없다. (Python 3.6 에서는 정적 타입 선언 가능)2) 동적언어이기 때문에 TDD를 하기에 적합하다.3) 파이썬은 간결성과 단순함으로 생산성이 높은 반면 런타임 오류가 발생할 수도 있다.4) 파이썬을 신뢰할 수 있는 유일한 방법은 테스트를 하는 것이다.파이썬 테스트 모듈 unittest이번 글에서는 unittest를 사용해 단위 테스트를 해보겠습니다. unittest는 이미 내장되어 있어 따로 설치하지 않아도 되는 표준 라이브러리입니다. 사용방법1) import unittest 2) unittest.TestCase 상속받는 하위 클래스 생성3) TestCase.assert 메소드를 사용하여 테스트 코드를 간략화4) unittest.main() 실행그럼 간단한 예제로 단위 테스트를 해보겠습니다.1.사칙연산 함수를 추가합니다.def add(a, b):     return a + b   def substract(a, b):     return a - b   def division(a, b):     return a / b   def multiply(a, b):     return a * b 2. unittest.TestCase 상속받아 테스트 클래스를 생성합니다. 아래는 각각의 함수 결과값을 비교해 텍스트를 출력하는 코드입니다.import unittest class TddTest(unittest.TestCase): def testAdd(self):         result = lib_calc.add(10, 20)         if result == 30:             print('testAdd OK')      def testSubstract(self):         result = lib_calc.substract(20, 30)          if result > 0:             boolval = True         else:             boolval = False if boolval == False:             print('testSubstract Error')      def testDivision(self):         try:             lib_calc.division(4, 0)         except Exception as e:             print(e)      def testMultiply(self):         result = lib_calc.multiply(10, 9)          if result < 100>             print('testMultiply Error') if __name__ == '__main__':     unittest.main() 3.결과: 해당 조건에 만족해 작성한 텍스트가 출력됩니다.이번에는 unittest에서 지원하는 TestCase.assert 메소드를 사용해 간략하게 소스를 수정해보겠습니다.TestCase.assert 메소드1) assertEqual(A, B, Msg) - A, B가 같은지 테스트2) assertNotEqual(A, B, Msg) - A, B가 다른지 테스트3) assertTrue(A, Msg) - A가 True인지 테스트4) assertFalse(A, Msg) - A가 False인지 테스트5) assertIs(A, B, Msg) - A, B가 동일한 객체인지 테스트6) assertIsNot(A, B, Msg) - A, B가 동일하지 않는 객체인지 테스트7) assertIsNone(A, Msg) - A가 None인지 테스트8) assertIsNotNone(A, Msg) - A가 Not None인지 테스트9) assertRaises(ZeroDivisionError, myCalc.add, 4, 0) - 특정 에러 확인1. TestCase.assert 메소드 사용TestCase.assert 메소드를 사용하여 에러를 발생시켜 보겠습니다.import unittest class TddTest(unittest.TestCase): def testAdd(self):         result = lib_calc.add(10, 20)          # 결과 값이 일치 여부 확인         self.assertEqual(result, 31)      def testSubstract(self):         result = lib_calc.substract(20, 10)          if result > 10:             boolval = True         else:             boolval = False # 결과 값이 True 여부 확인         self.assertTrue(boolval)      def testDivision(self):         # 결과 값이 ZeroDivisionError 예외 발생 여부 확인         self.assertRaises(ZeroDivisionError, lib_calc.division, 4, 1)      def testMultiply(self):         nonechk = True result = lib_calc.multiply(10, 9)          if result > 100:             nonechk = None # 결과 값이 None 여부 확인         self.assertIsNone(nonechk) if __name__ == '__main__':     unittest.main() 2. 결과1) 테스트가 실패해도 다른 테스트에 영향을 미치지 않음2) 실패한 위치와 이유를 알 수 있음다음으로 setUp(), tearDown() 메소드를 사용하여 반복적인 테스트 메소드 실행 전, 실행 후의 동작을 처리해보겠습니다.TestCase 메소드1) setUp() - TestCase클래스의 매 테스트 메소드가 실행 전 동작2) tearDown() - 매 테스트 메소드가 실행 후 동작 1. setUp(), tearDown() 메소드 사용- setUp() 메소드로 전역 변수에 값을 지정- tearDown() 메소드로 “ 결과 값 : ” 텍스트 출력import unittest class TddTest(unittest.TestCase): aa = 0     bb = 0     result = 0 # 매 테스트 메소드 실행 전 동작     def setUp(self):        self.aa = 10        self.bb = 20 def testAdd(self):         self.result = lib_calc.add(self.aa, self.bb)          # 결과 값이 일치 여부 확인         self.assertEqual(self.result, 31)      def testSubstract(self):         self.result = lib_calc.substract(self.aa, self.bb)          if self.result > 10:             boolval = True         else:             boolval = False # 결과 값이 True 여부 확인         self.assertTrue(boolval)      def testDivision(self):         # 결과 값이 ZeroDivisionError 예외 발생 여부 확인         self.assertRaises(ZeroDivisionError, lib_calc.division, 4, 1)      def testMultiply(self):         nonechk = True self.result = lib_calc.multiply(10, 9)          if self.result > 100:             nonechk = None # 결과 값이 None 여부 확인         self.assertIsNone(nonechk)      # 매 테스트 메소드 실행 후 동작     def tearDown(self):         print(' 결과 값 : ' + str(self.result))   if __name__ == '__main__':     unittest.main() 2. 결과- setUp() 메소드로 지정한 값으로 테스트를 수행 - tearDown() 메소드로 각각의 테스트 메소드 마다 “ 결과 값 : ” 텍스트 출력실행 명령어 여러 옵션을 사용하여 실행 결과를 출력해보겠습니다.실행 명령어python -m unittest discover [option]1. -v : 상세 결과 2. -f : 첫 번째 실패 또는 오류시 중단3. -s : 시작할 디렉토리4. -p : 테스트 파일과 일치하는 패턴5. -t : 프로젝트의 최상위 디렉토리1. 상세 결과테스트 메소드명 및 해당 클래스명 출력 2. 첫 번째 실패 또는 오류시 중단첫 번째 테스트에서 오류 발생하여 중단3. 여러 옵션 실행현재경로 디렉토리 안에 tdd_test*.py 패턴에 속하는 모든 파일의 상세 결과Conclusion지금까지 파이썬에서 unittest 모듈을 이용한 테스트 코드를 작성했습니다. 처음에는 귀찮고 번거롭지만 테스트 코드를 먼저 작성하는 습관을 길러보세요. 분명 높은 품질의 소스코드를 만들 수 있을 겁니다!참고Python 테스트 시작하기파이썬 TDD 101글곽정섭 과장 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발자 #개발팀 #인사이트 #경험공유 #파이썬 #Python

기업문화 엿볼 때, 더팀스

로그인

/