美文网首页
关于自动化测试的学习笔记

关于自动化测试的学习笔记

作者: l蓝色梦幻 | 来源:发表于2018-03-08 10:46 被阅读28次

    Mousepose

    屏幕上鼠标位置/按键高亮

    关于 LeanCloud 的测试情况

    • 存储框架,数据层.适合写单元测试
    • 项目早起就有单元测试
    • 提交一个 PR, Jenkins 上跑单元测试
    • 覆盖率 80%
    • 直接写测试, 用来检测正在开发的新接口
    • 直接写测试, 重现 bug
    • 积累的测试越多越强大
    • 两种场景: 改完一些代码后, 本地跑相关的测试, 发现某些不通过: Jenkins 自动化跑测试的时候, 发现最新改动引起其他问题, 某些测试不通过
    • 放心的发布与重构, 剩下手动验证的时间

    为什么要写单元测试

    • 当发现自己改了代码后,经常需要手动验证是否正常时
    • 客户反馈问题, 使用测试找到问题
    • 开发新接口, 编写相应代码后加入测试
    • 发现改了代码后, 经常引起其他地方的 bug 时
    • 多人合作的项目, 可能交给其他人的项目
    • 高质量/流行的开源项目一般都有丰富的单元测试

    怎么写单元测试

    • 模块化代码, 数据层与 UI 层分离
    • 最少的测试代码达到最高的覆盖率
    • 异步处理
    • 框架选择
    • 覆盖率

    expecta

    框架平息

    • expecta expect(error).not.beNil()
    • specta describe("") it("")
    • Kiwi describe("") it("")
    • Tdd和 BDD 框架的坏处: 和 Xcode 结合不好, 比如没有测试按钮, 左边栏没有列全单元测试

    iOS 单元测试异步处理

    #define WAIT(name)                                                          \
    do {                                                                        \
        [self expectationForNotification:name object:nil handler:nil];          \
        [self waitForExpectationsWithTimeout:60 handler:nil];                   \
    } while(0)
    
    #define NOTIFY(name)                                                            \
    do {                                                                            \
        [[NSNotificationCenter defaultCenter] postNotificationName:name object:nil];\
    } while(0)     
    
    
    - (void)waitNotification:(const void *)notification {
        NSString *name = [NSString stringWithFormat:@"%p", notification];
        [self expectationForNotification:name object:nil handler:nil];
        [self waitForExpectationsWithTimeout:AV_YEAR_SECONDS handler:nil];
    }
    
    - (void)postNotification:(const void *)notification {
        NSString *name = [NSString stringWithFormat:@"%p", notification];
        [[NSNotificationCenter defaultCenter] postNotificationName:name object:nil];
    }
    

    覆盖率

    从 Xcode7 开始,自带覆盖率高爆功能. 设置要点:

    1. Scheme 中开启 Gather Coverage Data
    2. 针对 App Target 来测试, 而非 Test Target
    3. We've Got You Covered
    4. 如何查看单元测试具体运行需要了解哪些代码
    覆盖率.png

    Xcode 7 之后的脚本

    xcodebuild                          \
        -workspace AVOS.scworkspace     \
        -scheme AVOSCloudIMTests        \
        -sdk iphonesimulator            \
        clean                               \
        test &&                         \
    xcodebuild                          \
        -workspace AVOS.scworkspace     \
        -scheme AVOSCloudTests          \
        -sdk iphonesimulator            \
        clean                               \
        test                                \
    
    

    远程自动化测试

    • 搭建 Jenkins
    • 本地空闲的 Mac 电脑或将 Mac 电脑拿到数据中心
    • 测试脚本, 设置项目
    • Github PR 构建插件: ghprb
    • 配置 Jenkins Job
    • 本地测试能发挥出测试的 70% 好处, 远程自动化则发挥出 100% 的好处
    • Github 上配置 Setting->Webhooks ,添加搭建的自动化测试平台, 就可以进行自动化测试

    Jenkins 配置

    • 要让 Jenkins 能读到你的代码
    • 配置 Hook, 当提交 Github PR 时, 发送响应的事件到 Jenkins 上
    • Jenkins 要知道是哪一个 PR, 来拉取最新的代码
    • 设置 Jenkins 测试脚本
    • 当测试失败之后, 要让 Genkins 通知 Github 页面
    • 测试失败后, 可发送通知到 Slack 或邮件
    export LC_ALL="en_US.UTF-8"
    pod install --verbose --no-repo-update
    if [ -e test.sh] then 
        ./test.sh
    fi
    

    Jenkins 如何知道测试失败或者成功

    • 根据进程返回值. 如果是0, Jenkins 认为测试成功, 否则失败
    • Xcode 7 之前, 尽管 Xcodebuild test 失败了, 依然返回0; Xcode 7 之后, 失败了返回65

    Travis CI

    travis-ci

    • 设置 Test Scheme 为 shared
    • Travis 上连接 Github 账号, 读取项目
    • .travic.yml
    • Travis 免费版可以给开源项目测试, 收费版给私有项目测试
    • Travis 测试比较慢
    • 如果会用 Jenkins 自己搭建自动化测试框架, Travis 眨眼间就会
    language: objective-c
    xcode_workspace: XXX.xcworkspace
    xcode_scheme: XXX
    

    远程打包发布

    • 发布脚本
    • Jenkins 上配置 Job 运行
    • LeanCloud 上是发布框架, 远程打包 SDK 推送到 Github 仓库, 同步网站更新
    • 针对 App, 四核没必要远程打包发布

    实现思路

    • Jenkins 读取你的代码
    • 读取发布版本
    • unlock keychain, 构建一个项目会弹出输入密码框, 来读取签名的 keychain
    execute_command('security unlock-keychain -p "xxx" ~/Library/Keychains/login.keychain')
    

    在命令行中解Keychain, 一般会弹框输入密码

    Lioo

    • 查看 framework 的编译架构 lipo -info
    • lipo 合并不同架构的 framework

    Pod

    • 本地引用 Pod, --no-repo-update --verbose
    • 发布 pod, podfile 配置

    自动化 Pod 推送

    def push_podspec_in_path(path)
        iterate_r(path, 'podspec') do |file|
            podspec_name = File.basename(file, ".podspec")
            podspec_version = version[1..-1]
            exists = is_podspec_exists(podspec_name, podsepc_version)
            if exists
                log("#{podspec_name} #{podsepc_version} exists!")
                next
            else 
                log("#{podspec_name} #{podsepc_version} not exists, now try to push it")
            end
            
            ok = false
            for i in 0..10
                ok = system("pod truck push #{file} --verbose --allow-warning")
                if ok
                    log("success to push #{file}")
                    break
                else 
                    log("failed to push #{file}")
                end
            end
            
            if !ok
                exit_with_info("")
            end
        end
    end
    

    重复推送 Podspec

    def is_podspec_exists(name, version)
        podspec_url = "https://github.com/CocoaPods/Specs/blob/master/Specs/#{name}/#{version}/#{name}"
        url = URI.parse(podspec_url)
        req = Net::HTTP::Get.new(url.to_s)
        http = Net::HTTP.new(url.host, url.port)
        http.use_ssl = true
        res = http.request(req)
        res.code == '200'
    end
    

    好用的工具

    • Revel(越狱) 分析任意 app 的 ui 界面
    • Flex(越狱) 分析任意 App 的网络请求, ui 界面, 本地文件, NSUserDefaults, Log 等

    相关文章

      网友评论

          本文标题:关于自动化测试的学习笔记

          本文链接:https://www.haomeiwen.com/subject/ffgefftx.html