惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
博客园 - 叶小钗
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
V
V2EX
IT之家
IT之家
J
Java Code Geeks
Hacker News - Newest:
Hacker News - Newest: "LLM"
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
GbyAI
GbyAI
D
Docker
S
Secure Thoughts
Recent Announcements
Recent Announcements
Webroot Blog
Webroot Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
云风的 BLOG
云风的 BLOG
博客园_首页
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Security Archives - TechRepublic
Security Archives - TechRepublic
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
News | PayPal Newsroom
S
Security @ Cisco Blogs
I
InfoQ
Last Week in AI
Last Week in AI
SecWiki News
SecWiki News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
W
WeLiveSecurity
T
Troy Hunt's Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
美团技术团队
T
The Blog of Author Tim Ferriss
Google DeepMind News
Google DeepMind News
Martin Fowler
Martin Fowler
B
Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Scott Helme
Scott Helme
T
Tor Project blog
Know Your Adversary
Know Your Adversary
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
Recorded Future
Recorded Future
C
Cyber Attacks, Cyber Crime and Cyber Security
AI
AI
G
Google Developers Blog

Peter Steinberger

OpenClaw, OpenAI and the future | Peter Steinberger Shipping at Inference-Speed | Peter Steinberger The Signature Flicker | Peter Steinberger Just Talk To It - the no-bs Way of Agentic Engineering | Peter Steinberger Claude Code Anonymous | Peter Steinberger Live Coding Session: Building Arena | Peter Steinberger My Current AI Dev Workflow | Peter Steinberger Essential Reading for Agentic Engineers - August 2025 | Peter Steinberger Just One More Prompt | Peter Steinberger Poltergeist: The Ghost That Keeps Your Builds Fresh | Peter Steinberger Don't read this Startup Slop | Peter Steinberger Essential Reading for Agentic Engineers - July 2025 | Peter Steinberger Self-Hosting AI Models After Claude's Usage Limits | Peter Steinberger Logging Privacy Shenanigans | Peter Steinberger VibeTunnel's first AI-anniversary | Peter Steinberger Making AppleScript Work in macOS CLI Tools: The Undocumented Parts | Peter Steinberger Peekaboo 2.0 – Free the CLI from its MCP shackles | Peter Steinberger Command your Claude Code Army, Reloaded | Peter Steinberger Essential Reading for Agentic Engineers | Peter Steinberger Slot Machines for Programmers: How Peter Builds Apps 20x Faster with AI | Peter Steinberger My AI Workflow for Understanding Any Codebase | Peter Steinberger stats.store: Privacy-First Sparkle Analytics | Peter Steinberger Showing Settings from macOS Menu Bar Items: A 5-Hour Journey | Peter Steinberger VibeTunnel: Turn Any Browser into Your Mac's Terminal | Peter Steinberger Vibe Meter 2.0: Calculating Claude Code Usage with Token Counting | Peter Steinberger llm.codes: Make Apple Docs AI-Readable | Peter Steinberger Automatic Observation Tracking in UIKit and AppKit: The Feature Apple Forgot to Mention | Peter Steinberger Peekaboo MCP – lightning-fast macOS screenshots for AI agents | Peter Steinberger Migrating 700+ Tests to Swift Testing: A Real-World Experience | Peter Steinberger Commanding Your Claude Code Army | Peter Steinberger Code Signing and Notarization: Sparkle and Tears | Peter Steinberger Vibe Meter: Monitor Your AI Costs | Peter Steinberger Claude Code is My Computer | Peter Steinberger Stop Over-thinking AI Subscriptions | Peter Steinberger Introducing Demark: HTML in. MD out. Blink-fast. | Peter Steinberger The Future of Vibe Coding: Building with AI, Live and Unfiltered | Peter Steinberger MCP Best Practices | Peter Steinberger Finding My Spark Again | Peter Steinberger Top-Level Menu Visibility in SwiftUI for macOS | Peter Steinberger Fixing keyboardShortcut in SwiftUI | Peter Steinberger Supporting Both Tap and Long Press on a Button in SwiftUI | Peter Steinberger On Using Apple Silicon Mac Mini for Continuous Integration | Peter Steinberger Apple Silicon M1: A Developer's Perspective | Peter Steinberger Gardening Your Twitter: Curating Your Timeline | Peter Steinberger Gardening Your Twitter: Growing Your Followers | Peter Steinberger Forbidden Controls in Catalyst: Optimize Interface for Mac | Peter Steinberger Disabling Keyboard Avoidance in SwiftUI's UIHostingController | Peter Steinberger The State of SwiftUI | Peter Steinberger Logging in Swift | Peter Steinberger Building with Swift Trunk Development Snapshots | Peter Steinberger Calling Super at Runtime in Swift | Peter Steinberger zld — A Faster Version of Apple's Linker | Peter Steinberger How to Fix LLDB: Couldn't IRGen Expression | Peter Steinberger Updating macOS on a Hackintosh | Peter Steinberger InterposeKit — Elegant Swizzling in Swift | Peter Steinberger The Great Mac Catalyst Text Input Crash Hunt | Peter Steinberger Jailbreaking for iOS Developers | Peter Steinberger Network Kernel Core Dump | Peter Steinberger How to macOS Core Dump | Peter Steinberger Kernel Panics and Surprise boot-args | Peter Steinberger The LG UltraFine 5K, kernel_task, and Me | Peter Steinberger Let's Try This Again | Peter Steinberger How We Work at PSPDFKit | Peter Steinberger Swizzling in Swift | Peter Steinberger WWDC for First-Timers, 2019 Edition | Peter Steinberger Challenges of Adopting Drag and Drop | Peter Steinberger Marzipan: Porting iOS Apps to the Mac | Peter Steinberger How to Use Slack and Not Go Crazy | Peter Steinberger Hardcore Debugging - Heavy Weapons for Hard Bugs | Peter Steinberger Binary Frameworks in Swift | Peter Steinberger Even Swiftier Objective-C | Peter Steinberger The Case for Deprecating UITableView | Peter Steinberger Running tests with Clang Address Sanitizer | Peter Steinberger UI testing on iOS, without busy waiting | Peter Steinberger Hiring a distributed team | Peter Steinberger Writing Good Bug Reports | Peter Steinberger Real-time collaboration, Apple, and you | Peter Steinberger Efficient iOS Version Checking | Peter Steinberger Investigating Thread Safety of UIImage | Peter Steinberger Swifty Objective-C | Peter Steinberger Running UI Tests on iOS With Ludicrous Speed | Peter Steinberger A Pragmatic Approach to Cross-Platform | Peter Steinberger Surprises with Swift Extensions | Peter Steinberger Using ccache for Fun and Profit | Peter Steinberger UITableViewController designated initializer woes | Peter Steinberger Researching ResearchKit | Peter Steinberger The curious case of rotation with multiple windows on iOS 8 | Peter Steinberger UIKit Debug Mode | Peter Steinberger Retrofitting containsString: on iOS 7 | Peter Steinberger A Story About Swizzling "the Right Way™" and Touch Forwarding | Peter Steinberger Hacking with Aspects | Peter Steinberger Fixing UITextView On iOS 7 | Peter Steinberger Fixing What Apple Doesn't | Peter Steinberger How To Inspect The View Hierarchy Of Third-Party Apps | Peter Steinberger Fixing UISearchDisplayController On iOS 7 | Peter Steinberger Smart Proxy Delegation | Peter Steinberger Adding Keyboard Shortcuts To UIAlertView | Peter Steinberger How To Center Content Within UIScrollView | Peter Steinberger UIAppearance for Custom Views | Peter Steinberger Hacking Block Support Into UIMenuItem | Peter Steinberger
Converting Xcode Test Runs to JUnit, the Fast Way | Peter Steinberger
Peter Steinberger · 2016-08-11 · via Peter Steinberger

Testing is very important at PSPDFKit. We’re building an SDK. When you give your API to other developers, there are many more things that can go wrong. For a long time, we’ve been using either a combination of xcodebuild with xcpretty or Facebook’s xctool. No tool is perfect though. xctool is an alternative to xcodebuild but uses much of it under the hood and often breaks when Xcode is updated. At some point Facebook deprecated it, and currently it doesn’t work with Xcode 8 anymore. xcpretty is really good. It parses the very verbose output of xcodebuild and prints it into something sane that a human can read. A big shout-out to Marin Usalj, who maintains the project.

There are a few inherent problems with parsing an undocumented log output with regular expressions. Things might get lost if no regex matches, or parsing becomes extremely slow if you log too much. All of this, and much more, has happened to us. It is not really xcpretty’s fault — it tries hard. It’s more an inherent problem and changing output between Xcode versions doesn’t help either. (Oh, you think xcodebuild can’t be any more verbose? Did you know about the undocumented log level 5? Have fun!)

I was discussing this with “Mr. Fastlane” Felix on his last visit to Vienna over a (fake) Club Mate.

Lobbying hard to get @KrauseFx to rewrite xcpretty inside fastlane. How much Club Mate will I need?

We were talking about potentially rewriting xcpretty. However, after some more drinking talking, we figured that Xcode Server is a thing and that there must be a way how xcodebuild could pass the test results to it. JSON maybe? Of course not, but there is a plist! We were not the first to discover this, just the first who had the idea of writing a converter that takes the plist output and converts it into JUnit format.

Why JUnit? Because that’s what Jenkins eats for breakfast. So naturally, trainer was born. PSPDFKit is a huge project (PDF is hard, and turing-complete) and we have a few thousand tests across about 10 sub-projects. So it turned out to be a good test case to get trainer up and running. Since Xcode didn’t close its log pipe (we reported this here as rdar://27447948 and it has sinced been fixed in beta 4) and our sad attempts on working around this issue were not very successful, trainer was our best way to get Jenkins green blue again.

Before it was even publicly announced, Twitter had already adopted it and saw a 10x performance increase in JUnit report generation.

It also made our CI much, much less flaky, since random weird log messages no longer confuse the test converter. You can even run this in combination with xcpretty and get the best of both worlds. A flawed, but great version a human can read and a separate converter that translates test results from a (so far) stable-looking plist format.

So far trainer seems to be the only converter, though there are other tools that try to solve this differently, such as the recently open-sourced fbxctest by Facebook.

trainer is currently provided as standalone tool, with a built-in fastlane plugin, so it’s easy to get started if you’re already using fastlane. It focuses on one thing, generating a JUnit file that is supported by all major Continuous Integration systems like Jenkins, Circle and Travis. Combining this with danger and the danger-junit plugin by @orta, you can show the exact test failures right in your pull request. This solves the common phenomenon of “PR and Run”, which happens on many major open source projects. Typically, a developer submits a pull request on GitHub (often a simple one), which causes a test failure. By the time the test failures are shown on GitHub, the author has already closed the page. After a “PR and Run” occurs, the maintainer then has to manually ping the author to fix the tests. By using danger, the failed tests will automatically be posted as a comment on the PR, triggering an email notification to be sent to the author. (See example PR)

Danger Output

A big thanks to Felix for building trainer! We hope to see this under the fastlane umbrella soon.

SO BUILD. WOW.