Wednesday, May 6, 2020
Swift : class vs struct
Friday, March 24, 2017
#AWS #IAM introductions
What is IAM?
What does IAM give you?
Critical Terms:
Sunday, March 12, 2017
#AWS Root path access denined on #S3 Static Website Hosting with #CloudFront
Problem. Access Denied on root path of cloudfront's endpoint.
I see Access Denined even I configured 'Index Document' on S3.
And access root path with S3' endpoint works perfect.
Answer. Default Root Object on CloudFront
Friday, March 10, 2017
#Android How to setup test environment with Robolectric
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile "org.robolectric:robolectric:3.3.1"
testCompile "org.robolectric:shadows-multidex:3.0"
testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 22)
public class LoginActivityTest {
private LoginActivity subject;
private EditText editTextId;
private EditText editTextPass;
private Button buttonLogin;
@Before
public void setUp() throws Exception {
subject = Robolectric.setupActivity(LoginActivity.class);
editTextId = (WashEditText) subject.findViewById(R.id.layoutEmail);
editTextPass = (WashEditText) subject.findViewById(R.id.layoutPw);
buttonLogin = (Button) subject.findViewById(R.id.btnLogin);
subject.loginCommunicator = mock(LoginCommunicator.class);
}
@Test
public void loginWithoutEmail() throws Exception {
buttonLogin.performClick();
ShadowLooper.idleMainLooper();
verify(subject.loginCommunicator, never()).requestLoginEmail(eq("liketaehoon@gmail.com"), eq(CommonUtil.password("1234")), anyString(), any(WashResponse.Listener.class));
assertThat( ShadowToast.getTextOfLatestToast(), equalTo(subject.getString(R.string.error_input_email)));
}
}
Saturday, December 24, 2016
파이썬 개발 환경 for osx.
pyenv
파이썬 버전 관리
brew install pyenv
https://github.com/yyuu/pyenv
pyenv-virtualenv
파이썬 가상 환경
brew install pyenv-virtualenv
https://github.com/yyuu/pyenv-virtualenv
autoenv
폴더별 SHELL 환경 설정 ( 꼭 파이썬이 아니더라도 )
brew install autoenv
https://github.com/kennethreitz/autoenv
vim
말이 필요 없는
Tuesday, December 20, 2016
[번역][Swift 공식 블로그] Objective-C [id] 를 Swift [Any] 로 사용하기. 1부
Objective-C [id] 를 Swift [Any] 로 사용하기 1부
원문 : Objective-C id as Swift AnySwift3를 이전버전에 비해 좀더 강력하세 Objective-C API를 사용할수 있습니다.
예를들어, Swift2에서는 [id](ObjC)형을 값과,Class 종류만을 가질수 있는 [AnyObject](Swift)형으로 사용할수 있었습니다. Swift2에서는 NSString이나 NSArray 혹은 다른 Foundation 에서 제공하는 형을 기대하는 CoCoa API에서 사용될수 있는 [String][Array][Dictionary][Set] 같은 형으로 묵시적으로 캐스팅 하여 사용할수 있었습니다. 이러한 방식은 일관성이 없고, AnyObject에 실제 어떤 형이 들어 있는지 알수 없어, 버그의 소지가 높았습니다.
Swift3에서는 [id] 타입을 class,enum,struct 혹은 다른 Swift type의 어떠한 타입의 값을 서술할수 있는 [Any] 타입으로 매핑합니다. 이러한 변화는 Swift 에서 사용되는 Objective-C API를 더 유연하게 사용할수 있게 합니다. 왜냐하면 Swift로 정의된 데이터를 Objective-C API에 바로 전달함으로써, Swift type를 분리해서 일일이"box" types로 치환하는 작업을 제거하기 때문입니다. 이러한 특성은 NSArray, NSDictionary, NSSet 과 같은 Collection Class 에도 적용됩니다. 예를들어 hashed container인 [Dictionary] 와 [Set] 같은 경우는 [Hashable] protocol을 구현하는 [AnyHashable] 타입으로 변환되게 됩니다.
| ObjC | Swift 2 | Swift 3 |
| [id] | AnyObject | Any |
| [NSArray *] | [AnyObject] | [Any] |
| [NSDictionary *] | [NSObject:AnyObject] | [AnyHashable:Any] |
| [NSSet *] | Set | Set |
Method 오버라이딩과 Protocol 구현
// Swift 2
class Foo: NSObject, NSCopying {
override func isEqual(_ x: AnyObject?) -> Bool { ... }
func copyWithZone(_ zone: NSZone?) -> AnyObject { ... }
}
// Swift 3
class Foo: NSObject, NSCopying {
override func isEqual(_ x: Any?) -> Bool { ... }
func copy(with zone: NSZone?) -> Any { ... }
}
Untyped Collections
// Swift 2
struct State {
var name: String
var abbreviation: String
var population: Int
var asPropertyList: [NSObject: AnyObject] {
var result: [NSObject: AnyObject] = [:]
// Implicit conversions turn String into NSString here…
result["name"] = self.name
result["abbreviation"] = self.abbreviation
// …and Int into NSNumber here.
result["population"] = self.population
return result
}
}
let california = State(name: "California",
abbreviation: "CA",
population: 39_000_000)
NSNotification(name: "foo", object: nil,
userInfo: california.asPropertyList)
// Swift 2
struct State {
var name: String
var abbreviation: String
var population: Int
var asPropertyList: NSDictionary {
var result = NSMutableDictionary()
// Implicit conversions turn String into NSString here…
result["name"] = self.name
result["abbreviation"] = self.abbreviation
// …and Int into NSNumber here.
result["population"] = self.population
return result.copy()
}
}
let california = State(name: "California",
abbreviation: "CA",
population: 39_000_000)
// NSDictionary then implicitly converts to [NSObject: AnyObject] here.
NSNotification(name: "foo", object: nil,
userInfo: california.asPropertyList)
// Swift 3
struct State {
var name: String
var abbreviation: String
var population: Int
// Change the dictionary type to [AnyHashable: Any] here...
var asPropertyList: [AnyHashable: Any] {
var result: [AnyHashable: Any] = [:]
// No implicit conversions necessary, since String and Int are subtypes
// of Any and AnyHashable
result["name"] = self.name
result["abbreviation"] = self.abbreviation
result["population"] = self.population
return result
}
}
let california = State(name: "California",
abbreviation: "CA",
population: 39_000_000)
// ...and you can still use it with Cocoa API here
Notification(name: "foo", object: nil,
userInfo: california.asPropertyList)
[AnyHashable] Type
2부에서 계속
Explicit Conversion for Unbridged Context
[AnyObject] Member Lookup
Swift Value Types in Objective-C
Linux Portability
Learning More
Wednesday, December 14, 2016
[Introduction to Algorithm] 4. Heaps and Heap Sort
4. Heaps and Heap Sort
Priority Queue
key를 가지는 각 요소를 가지는 집합이라고 볼수 있으며, 추가, 최대값, 최대값 추출, 키 값 변경등을 할수 있다.Heap
Priority Queue의 Array 형식의 구현채로, 시각화하면 거의 완벽한 Binary Tree 형태를 가진다.Max Heap Property
주어진 node의 key 값은 항상 해당 node의 children node의 key 보다 항상 크다.Min Heap
Max Heap 과 반대의 특성을 가진다.Heap as a Tree
root of tree : array의 첫번째 element. (i=1)parent(i) = i/2 : node i 의 부모 node
left(i) = i*2 : node i의 왼쪽 child
right(i) = i*2+1 node i의 오른쪽 child
Binary Heap의 높이는 항상 O(lg n)
Heap Operation
build_max_heap : 정렬되지 않은 array를 max-heap 으로 변환하는 작업max_heapify : max heap property를 하나만 어기는 경우, 이를 교정하는 작업
insert, extract_max,heapsort
Max_heapify
Max_heapify (example)
Time = ? O(log n)
Max_Heapify Pseudocode
l = left(i)r = right(i)
if ( l<= heap-size(A) and A[l] > A[i]) then largest = l else larges = i
if (r<= heap-size(A) and A[r] > A[largest]) then largest = r
if largest != i then exchange A[i] and A[largest] Max_Heapify(A, largest)
Build_Max_Heap(A)
Build_Max_Heap(A) Analysis
Heap-Sort
영상 바로가기 :
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/lecture-videos/lecture-4-heaps-and-heap-sort/
Heap Sort vs x-Sorts ?
흐트러진 마음을 잡아 보고자 써보는 '애자일 소프트웨어 개발 선언'
애자일 소프트웨어 개발 선언
애자일 선언 이면의 원칙
Tuesday, December 13, 2016
[Cracking the Coding Interview] Chap.9 System Design and Scalability.
여기에 어떤 함정도, 특별한 알고리즘이 필요 한것이 아니고.
당신이 이런 문제들을 어떻게 해결하는지 보기 위함이다.
질문을 하고, 면접관과 함께 토론해야 한다.
이런 질문에 답하는 방법
이야기를 하라.넓게 생각하라, 특정 알고리즘 혹은 특정 부분에 몰두 하지 말고, 큰 그림을 봐야 한다.
화이트 보드를 적극 활용하고, 면접관이 우려하는 점에 대해 명확히 이해하라.
조심스럽게 가정하고, 그런 가정들에 대해서 면접관에게 전파해라.
평가는 필요 할때만해라.
Design : Step-by-Step
혼자서 문제를 풀려고 하지말고, 대화를 하면서 문제를 풀어 나가야 한다.Step 1 : 문제의 범위 산정하기.
면접자가 요청한 문제가 내가 이해한것과 같은지 확인 해야 한다.예 : TinyUrl
permenant 한지, UserAccount 시스팀이 필요 한지, 클릭횟수 추적이 필요 한지 등을 물어 봐야 한다. 질문이 끝나고 나면 아래와 같이 리스트업한다.
* Shortening a URL to a TinyUrl
* Analytics for a URL
* Retrieving the URL associated with a TinyURL.
* User accounts and link management.
Step 2 : Make Reasonable Assumptions
어떠한 가정을 하는건 좋지만, 항상 정당한 이유가 있어야한다.무한한 메모리를 사용한다고 하거나, 하루에 100명만 사용한다고 하거나 하면 안된다.
Step 3 : Draw the major components
Frontend 서버나, Data Store 서버 등의 중요 컴포넌트들을 그리면 된다.이 단계에 대해서 Scalability 같은거는 접어 두고 가능한한 간단한척 하고 그리는게 좋다.
Step 4 : Identify the Key Issues
기본적인 디자인이 완료 되면, 어떤 문제가 있을지 생각해두는게 좋다.병목지점이라던지, 이 시스템을 만드는데 있어서 가장 큰 도전이 될만한 것들에 대해서 생각해두도록 하자.
예를들면 TinyURL은 보통 불규칙적인 접근 패턴을 가지는데, 커뮤니티등에 공유되어서 갑자기 엄청 많이 접근 될수도 있다.
Step 5: Redesign the the Key Issues.
정리한 이슈들을 해결할수 있도록 Diagram을 업데이트.이때 당신이 디자인한 결과의 한계에 대해서 오픈마인드를 가져야한다. 면접과는 이를 인지할테고 그와 적극적으로 소통해야 한다.
Algorithms that Scale : Step-By-Step
보통은 전체 시스템을 재디자인하라고 하지 않고, 특정 기능이나 알고리즘에 대해서 다시 작성할것을 요구 받는다. 이때 명심해야 할점을 Scalability 를 고려해야한다는 점이다.Step 1 : Ask Questions
앞서 말한것처럼 요구 사항을 제대로 인지 해야한다.Step 2 : Make Believe
일단 무한한 메모리를 가진 머신을 통해서 처리할수 있다고 생각하고 답을 작성하라.Step 3 : Get Real
다시 원래 문제로 돌아가서, 얼마나 많은 데이터를 한번에 처리 할수 있으며, 데이터를 쪼개었을때 나타나는 문제에 대해서 생각해봐야 한다. 보통은 한 머신이 데이터를 볼때 다른 데이터를 어떻게 찾을수 있는지가 문제이다.Step 4 : Solve Problems
이제 발생할수 있는 문제들에 해결 방안을 제시 해야 한다. 문제가 해결 되었을 수도 있고, 아닐수도 있다. 문제가 해결 되지 않았다거나, 다른 문제가 발생하면 그문제들에 대해서 깊게 고민해야 한다. 지금 당장 완벽한 시스템을 만드는게 중요한것이 아니라, 문제를 찾아내고, 수정하고 하는 과정이 중요한것이다.Key Concepts
Horizontal vs Vertical Scaling
* Vertical Scaling 은 특정한 node 에 대한 성능향상, 예를 들어서 메모리를 늘리는 등.* Horizontal Scaling 은 node 수를 늘리는 방식이다. 예를 들면 서버 수를 늘려서 부하를 분산시키는것이다.
Load Balancer
뭐 말이 필요 없는듯. 말 그대로Database Denormalization and NoSQL
시스템이 커질수록 RDBMS 에서의 JOIN 연산이 병목지점이 된다.Denormalization(역정규화)를 하면 이런 문제를 피할수 있다.
NoSQL을 이용해서 처리할수도 있는데, NoSQL은 관계형 DBMS가 아니기 때문에 JOIN 연산이 없고, scale하기 좋게 디자인 되어 있다.
Database Partitioning(Sharding)
DB Sharding은 데이터를 쪼개는 기능이다.* Vertical Partitioning
가장 기초적인 샤딩 기법으로, 테이블별로 DB를 나누는 것이다.
Vertical Partitioning의 단점은 분리된 DB일지라고 그 DB가 매우 커지면 또다시 다른 방법으로 Partitioning을 해야 한다는것이다.
* Key-Base(or Hash Based) Partitioning
Key 단위로 Table을 분리하는 기법. 문제는 서버를 추가할때 마다, Data Relocating 작업을 해야 하는데, 무지하게 비싼 작업이다.
* Directory-Base Partitioning
내가 찾는 데이터가 어디 잇는지, lookup table 을 통해 관리하는것이다. 서버 추가등의 이슈에 비교적 쉽게 대응할수 있지만, 두가지 결점이 있다.
첫번째로, lookup table에 문제가 생기면, 전체 장애로 이어진다.
두번째로 lookup table에 부하가 많이 걸린다.
대부분의 architecture들을 이런 기법들을 조합해서 사용한다.
Caching
생략.Asynchronous Processing & Queues
시간이 오래 걸리는 작업을 동기적으로 처리하면, 응답시간이 늦어 지기 때문에, 비동기로 처리해야 한다.때때로, pre-process 하는 형식으로 처리할수도 있다. 예를 들면 포럼에서 인기 잇는 포스트와 댓글 수 등을 미리 처리 하는것이다. 아주 약간 실데이터와 차이가 있을수 있지만 대부분 용납할수준일것이다. 실시간으로 데이터를 로딩해, 느린 응답시간을 가지는 것보다 훨씬 좋은 선택이다.
또 다른 때에는, 사용자에게 기다리게하고, 작업이 완료된것을 알려줘야 할수도 있다.
Networking Metrics
* Bandwidth한번에 보낼수 있는 최대 데이터양을 뜻한다. bps,gps 등으로 표기된다.
* Throughput
Bandwith가 한번에 보낼수 있는 최대 데이터양을 뜻하는 반면에 Throughput은 실제로 전송된 데이터의 크기를 뜻한다.
* Latency
end-to-end 과점에서 데이터가 전송되는데 걸리는 시간을 의미한다.
MapReduce
대용량 데이터를 처리하기 위한 기술.이름에 나와 있듯이 Map 과 Reduce 로 구분된다.
* Map은 데이터를 K,V 쌍으로 나누고.
* Reduce 는 특정 K를 가지고 여러방식으로 "reduce"한후 에 새로우 K,V를 만들어 낸다. 때때로 Reduce는 추가적인 Reduce를 위해 재귀적으로 사용될수 있다.
MapReduce 는 대용량 데이터를 Scalable 하게 병렬처리하는 기법이다.
Considerations
시스템 디자인을 할때는 Key Concepts 와 별개로 몇개의 이슈에 대해 생각해봐야 한다.* Failure
필연적으로 시스템 구성요소 오류가 나기 마련이고, 우리는 다수 혹은 모든 종류의 요소들의 오류에 대한 계획이 있어야 한다.
* Availability and Reliability
Availability 는 시스템 가용시간을 퍼센트 형태로 표기한것이다.
Reliability는 특정시간단위에 대해 시스템이 가용될수 있는 확률을 표기하는것이다.
* Read-heavy vs Write-heavy
읽기, 혹은 쓰기 편향적인 시스템이라면 디자인할때 고려해야 한다.
쓰기 편향이면, write-task를 queuing 하는 식으로 디자인할수 있다. ( 이때 쓰기 실패 일때는 대비해야 한다. ) 읽기 편향이면 cache를 꼭 넣어야 한다.
* Security
우리가 설계한 디자인에서 마주칠 Security 이슈에 대해 생각해봐야 한다.
이런 점들의 장단점에 대해 꼭 면접관과 공유 해야함을 기억해야한다.
There is no "perfect" system
어떤 시스템을 설계하든 한번에 완벽한 시스템 디자인은 없다. 언제나 장단점이 있기 마련이다. 두사람이 같은 시스템을 완전히 다르지만 훌륭하게 디자인할수 있다.이런 질문들에 대한 우리의 목표는, 요구사항을 이해하고, 문제를 구조화 한다음, 합리적인 가정을 토대로 시스템을 디자인하는것이며, 우리가 디자인한 시스템의 약점에 대해 열린 마음으로 대하는것이다.
Wednesday, December 7, 2016
해외에서 살아보기 #1
도전과 모험이 넘치는 스타트업 회사들에 몸담은 지도 5년 남짓한 시간.
더는 도전과 모험들은 새롭지 않고, 개발자로서의 역량은 나아가지 않고 뒷걸음만 치고 있는듯한 기분이 듭니다.
이러한 권태를 극복해보고자 해외에서 살아보고자 합니다.
첫 회사에 다닐 때, 운이 좋게도 유럽에서 약 6개월간의 파견근무를 한 적이 있습니다.
그때 보았던 해외 인력들이 작성했던 코드들은 창의적이면서도 구조적으로도 손색이 없었던 기억이 납니다. 코드를 작성하는 일은 논리적이기도 하고 기계적이기도 하지만 개인적으로는 미적인 영역에도 속한다고 생각합니다. 저 역시 그러하지만, 논리적인 코드를 작성하는 데는 익숙하지만 아름다운 코드를 작성해내지는 못하고 있습니다. 물론, 사람에 따라 다르겠지만 새로운 환경에서 다른 문화권의 사람들과 함께 일하는 것이 저에게 많은 자극을 줄 것이라 기대해봅니다.
저는 세상에서 가장 아름다운 여성의 남편이자, 4살 여자아이의 아빠입니다.
다행히, 아내 역시 해외에 살아 보고 싶은 로망이 항상 있었기에 적극적으로 찬성하며 좋아하지만, 해외 거주시 추가로 부담해야 할 렌트비, 육아 비용, 거기에 줄어들 소득을 생각하니 아마득하긴합니다. 아직 대소변도 제대로 가릴지 모르는 아이가 낯선 곳에서 말도 통하지 않는 친구와 선생님을 만나 잘 적응 할 수 있을지도 무척 걱정됩니다.
모든 도전이 그러하듯이 기대와 희망, 그리고 걱정과 불안이 동반합니다. 일단 실행하고 걱정과 불안은 그때그때 슬기롭게 해결할 수 있길 바라며, "해외에서 살아보기" 프로젝트를 시작해 봅니다.
Sunday, November 20, 2016
Lookup expressjs #2 lib/application.js
var compileETag = require('./utils').compileETag;
var slice = Array.prototype.slice;
이처럼 function들을 즉각적으로 사용하지 않고, variable로 사용하는 컨벤션이 있는데,
딱히 좋은지는 모르겠습니다.
compleEtag function 은 그렇다 치더라도,
slice 의 경우 코드에서 Array.prototype.slice 인지, user defined 된 slice 라는걸 알기 어렵다는 단점이 우선 눈에 띕니다..
좋은 점은 반복적으로 사용되면, 코드를 줄이는 효과가 있을것 같기는 한데,
slice 와 같이 well-known function 에 대해서 user define 하지 않는다는 규칙이 Team 에 존재한다면 괜찮을수 있다 생각됩니다.
그렇지만, new member가 숙지해야 될 규칙이 하나더 생기기에 역시 그렇게 좋은 효과로 보기 어렵습니다.
application.js 는 expressjs application 설정등 초기화하고, application life cycle 로 판단되는데, 일단 살펴 봐야 겠습니다.
app.defaultConfiguration = function defaultConfiguration() {
var env = process.env.NODE_ENV || 'development';
.....
debug('booting in %s mode', env);
this.on('mount', function onmount(parent) {
// inherit trust proxy
if (this.settings[trustProxyDefaultSymbol] === true
&& typeof parent.settings['trust proxy fn'] === 'function') {
delete this.settings['trust proxy'];
delete this.settings['trust proxy fn'];
}
// inherit protos
this.request.__proto__ = parent.request;
this.response.__proto__ = parent.response;
this.engines.__proto__ = parent.engines;
this.settings.__proto__ = parent.settings;
});
....
if (env === 'production') {
this.enable('view cache');
}
...
};
init() -> defaultConfiguration() 을 호출 하는데, 보시는 바와 같이 NODE_ENV 등의 각종 설정들이 초기화 됩니다.
한가지, production 모드 일때 view cache 가 활성화되는걸 볼수 있네요.
이점은 좀 유의 해야 할 필요가 있는것 같습니다.
Look up expressjs #1 ./lib/express.js
지금 주력으로 개발하고 있는 것은 nodejs + expressjs 입니다.
nodejs 는 원래 먼저 보고자 했는데, cpp 로 작성된 프로젝트 이기도 하고, nodejs 코딩 컨벤션에 대해서 좀더 알고 싶은 욕구를 해소하기 위해 expressjs 로 선정했습니다.
* expressjs ( http://express.js.com )
사이트 소개에 따르면 expressjs 는 경량하고도 유여한 Web Application Framework 입니다.
대부분의 nodejs로 구춘된 web application 은 expressjs 를 사용하고 있으며, 저도 현재 프로젝트에 사용하고 있습니다.
원래 이런 framework 선정 전에 먼저 살펴보고, 대안을 찾아 보고 장단점을 비교해봐야 하는데
지금이라도 늦기전에 살펴보도록 하겠습니다.
* index.js , lib/express.js
두파일이 expressjs lookup journey 의 입구 입니다.
예측해보건데, index.js 는 껍데기 이고, lib/express.js 는 좀더 디테일 한 껍데기 일것입니다.
네 index.js 는 lib/express.js를 require하여 export 하는 역할만 하니, skip
lib/express.js 를 살펴보겠습니다.
이 파일도 역시 application.js router.js response.js request.js 를 require 하는 껍데기에 가까운데, application object 생성하는 createApplication() function 이 정의 되어있고, 일부 deprecated method 에 대한 warning 을 담당하고 있습니다.
function createApplication() {
var app = function(req, res, next) {
app.handle(req, res, next);
};
mixin(app, EventEmitter.prototype, false);
mixin(app, proto, false);
app.request = { __proto__: req, app: app };
app.response = { __proto__: res, app: app };
app.init();
return app;
}
음.. 모르는게 한두가지 보이네요
mixin 과 __proto__
* mixin
https://en.wikipedia.org/wiki/Mixin
mixin 은 다른 class 의 method 를 상속하지(inherit) 하지 않고, 가져오는 (include) 개념이다.
언어에 따라 include 라고 하기도 한다고 하니, 그정도로 이해할수 있겠다.
nodejs application object가 EventEmitter와 proto를 mix 인해서 사용하는것으로 보면 될테고,
app 내에서, request, response module을 접근하고자 app.request, app.requese할 assign 하는 개념으로 보면 될것이다.
음.. 여기서 proto 는 또 뭐지 ㅎ
var proto = require('./application');
proto 는 application module 임으로, application은 EventEmitter, Application 모듈이 mixin 되었다고 보면 되겠다.
* __proto__
http://i5on9i.blogspot.kr/2014/09/proto-prototype.html
Tuesday, September 27, 2016
User Interface Testing - Testing with Xcode
Concepts and APIs
UI Testing 은 unit testing과 근본적으로 다르다.
Unit Testing은 app 스코프안에서 앱의 변수, 상태 등등을 전체적으로 접근 하며, function이나 method를 테스트 한다.
반면에 UI Testing은 User Level에서 테스트함으로 앱안의 함수등을 접근 할수 없다.
즉 User 관점에서 테스트 하는것이다.
APIs
- XCUIApplication
- XCUIElement
- XCUIElementQuery
** 가이드 문서에 별다른 내용이 없다 ㅠ
이건 가이드라기 보다 introduction에 가까운거 아닌가, 맨땅에 헤딩좀 해야 겠다.
Writing Tests of Asynchronous Operations- Testing with Xcode
XCTest에서 expectation 을 통해 Async Op.을 테스트 할수 있다.
XCTestCase+AsynchronousTesting.h 참조.
|
// Test that the document is opened. Because opening is asynchronous,
|
|
// use XCTestCase's asynchronous APIs to wait until the document has
|
|
// finished opening.
|
|
- (void)testDocumentOpening
|
|
{
|
|
// Create an expectation object.
|
|
// This test only has one, but it's possible to wait on multiple expectations.
|
|
XCTestExpectation *documentOpenExpectation = [self expectationWithDescription:@"document open"];
|
|
|
|
NSURL *URL = [[NSBundle bundleForClass:[self class]]
|
|
URLForResource:@"TestDocument" withExtension:@"mydoc"];
|
|
UIDocument *doc = [[UIDocument alloc] initWithFileURL:URL];
|
|
[doc openWithCompletionHandler:^(BOOL success) {
|
|
XCTAssert(success);
|
|
// Possibly assert other things here about the document after it has opened...
|
|
|
|
// Fulfill the expectation-this will cause -waitForExpectation
|
|
// to invoke its completion handler and then return.
|
|
[documentOpenExpectation fulfill];
|
|
}];
|
|
|
|
// The test will pause here, running the run loop, until the timeout is hit
|
|
// or all expectations are fulfilled.
|
|
[self waitForExpectationsWithTimeout:1 handler:^(NSError *error) {
|
|
[doc closeWithCompletionHandler:nil];
|
|
}];
|
|
}
|
Test Basics - Testing with Xcode
* 모든 소프트웨어는 각 컴포턴트(혹은 모듈을) 조합함으로써 만들어지고,
좋은 테스트라함은 해당 소프트웨어의 기능을 모두 아우를수 있는 레벨의 ( 콤포넌트 단위/ 혹은 콤포넌트를 조합하는 High Level)의 테스트를 수행하는것이다.
이를 위해 XCTests가 있다.
* Unit Tests
하위레벨의 콤포넌트(Model, ViewController, etc)를 테스트 하기에 적합.
> xcode 는 앱 뿐만 아니라, Library도 테스트 할수 있게, App/Library 두가지의 Context를 제공한다.
* Performance Mesure
특정 연산에 대한 성능 분석
* UI Tests.
어플리케이션의 workflow를 테스트 할수 있는 도구.
공부하는 사람.
내가 소프트웨어 엔지니어링을 매력적으로 느끼고, 직업으로 삼게 된 가장 큰 계기는,
이 직업은 꾸준히 공부할 수 있는, 아니 해야만 하는 직업이기 때문이다.
요 몇 년 나는 제대로 된 공부를 하지 않았다.
새로운 기술을 익히고 프로젝트에 적용 하는 것은 그 이전에도 해왔던 것으로 나에게 공부 코스트가 그렇게 큰일은 아니다.
삶의 권태를 느끼고 나를 둘러싼 환경을 변화시키고자 아등바등하고 있는 요즘,
또 한 번 내 이런 모습을 실감하고 나 자신부터 다시 붙잡고자 노력하고 있다.
공부하는 사람.
참 아름다운 말 아닌가. 꾸준히 나아가보자.
Monday, September 26, 2016
Testing with Xcode.
- Quick Start. Beginning with Xcode 5 and the introduction of the XCTest framework, the process of configuring projects for testing has been streamlined and automated with the test navigator to ease bringing tests up and running.
- Performance Measurement. Xcode 6 and later includes the ability to create tests that allow you to measure and track performance changes against a baseline.
- UI Testing. Xcode 7 adds capabilities for writing tests that exercise an app’s UI. It includes the ability to record UI interactions into source code that you can transform into tests.
- Continuous Integration and Xcode Server. Xcode tests can be executed using command-line scripts or configured to be executed by bots on a Mac running Xcode Server automatically.
- Modernization. Xcode includes a migrator for converting projects that have OCUnit tests to have XCTest tests.
Monday, February 29, 2016
블로깅의 재시작.
최근 몇년사이, 개발에 관심이 좀 떨어진것도 사실.
그에 따른 성능저하도 사실.
모든것을 인정하고 다시 시작한다는 기분으로 블로깅을 다시시작.
요새 관심 많은 nodejs 와 새롭게 꾸린 팀 Management에 대한 고민들로 가득찰듯합니다.
Sunday, October 31, 2010
[iOS] About 'autorelease'
Obj-C 로 개발하다가, 최초에 가장 헷갈렸던 개념중에 하나 인데,
autorelease라는 keyword탓이기도 하고, 지금 생각해보면, Apple탓이기도 한데,
"GC 가 알아서 해결해줄것임" 이라고 오해하기가 쉬운것 같다.
쉽게 얘기하면, autorelease를 특정 object에 걸어주면, release하는 시점을 연기한다고 이해 하면 된다.
그럼, 연기된 'release'가 언제 수행되는가 ?
그것을 알려면 NSAutoReleasePool 이라는 녀석을 알아야 한다.
object에 autorelease를 걸면,
current NSAutoReleasePool에 쌓이게 되고, NSAutoReleasePool이 Release될때, 함께 릴리즈 된다.
NSAutoReleasePool 은 Objective-C runtime에 의해 관리 되는데,
NSAutoReleasePool Object를 생성하게 되면, Stack처럼 쌓이게 되고,
top 에 있는 object가 current NSAutoReleasePool이 된다.
그래서 autorelease 를 많이 사용하는 application을 개발하면,
이 NSAutoReleasePool 관리에도 신경을 써서 개발해야만 한다.
Saturday, October 30, 2010
[iOS] display multiple lines with UILabel
UIKIT_EXTERN_CLASS @interface UILabel : UIView
{
....
}
@property(nonatomic) UILineBreakMode lineBreakMode; // default is UILineBreakModeTailTruncation. used for single and multiple lines of text
// this determines the number of lines to draw and what to do when sizeToFit is called. default value is 1 (single line). A value of 0 means no limit
// if the height of the text reaches the # of lines or the height of the view is less than the # of lines allowed, the text will be
// truncated using the line break mode.
@property(nonatomic) NSInteger numberOfLines;
You can set numberOfLines to display on UILabel set numberOfLines attribute.
[label setLineBreakMode:UILineBreakModeTailTruncation];
[label setNumberOfLines:2];
this code will display 2 line of text and if it overflow tail will be changed as "...."





