title: Xcode XCTest measure performance with async queues
body: <p>A framework that I have written for my app downloads different chunks of data that get processed. Naturally, larger sets of data take more time to process. To better investigate how to improve, I thought about writing Tests to measure performance to see where/if it's worth looking into.</p>
  <p>Generally, the <code>measure</code> block works, however, to avoid blocking the main thread, I process the data asynchronously. Because of that, I'm unable to measure &quot;from start to finish&quot; as the <code>measure</code> block disregards async blocks and finishes the Test before my async queue has finished processing all the data.</p>
  <p>I have written a minimal example to demonstrate what I mean.</p>
  <p><code>DownloadHandler</code> is the class that receives the data in my framework. <code>Database</code> is a class in my app and models where the data ends up and gets processed. In my app, the AppDelegate connects these two, but for the sake of the Test, the Test class does that in this case.</p>
  <p>This is the console output of what's happening:</p>
  <pre><code>File A
  Sent A to Database
  
  File B
  Sent B to Database
  
  File C
   Processed file A in Database 
   Processed file B in Database 
  Sent C to Database
  [End of Test]
  </code></pre>
  <p>But what I would need is to wait for the Test to have the queue to finish processing all the data before stopping. In other words, it's missing a final</p>
  <pre><code> Processed file B in Database 
  </code></pre>
  <p>Below you will find my example code to demonstrate. The actual implementation is much more complex with different handlers for different purposes but I simulate the &quot;work done&quot; with the <code>usleep</code></p>
  <p>DownloadHandler.swift</p>
  <pre><code>import Foundation
  
  public protocol HandlerDelegate {
      func interpretData(s: Character)
  }
  
  class DownloadHandler {
      
      var delegate: HandlerDelegate!
      
      func receivedFiles(files: String) {
          
          for file in files {
              print(&quot;\nFile \(file)&quot;)
              usleep(100000)
              delegate.interpretData(s: file)
              print(&quot;Sent \(file) to database&quot;)
          }
      }
      
  }
  </code></pre>
  <p>Database.swift</p>
  <pre><code>class Database {
      
      let serialQueue = DispatchQueue(label: &quot;databaseSerial&quot;)
      
      var entries = [Character]()
      
      func interpretData(s: Character) {
          serialQueue.async {
              usleep(100000)
              self.entries.append(s)
              print(&quot; Processed file \(s) in database&quot;)
          }
      }
      
  }
  </code></pre>
  <p>TestFrameworkTests.swift</p>
  <pre><code>import XCTest
  @testable import TestFramework
  
  class TestFrameworkTests: XCTestCase, HandlerDelegate {
      
      func interpretData(s: Character) {
          database.interpretData(s: s)
      }
      
      var handler = DownloadHandler()
      var database = Database()
      
      var testData = &quot;ABC&quot;
  
      func testPerformanceExample() throws {
          
          handler.delegate = self
          
          let options = XCTMeasureOptions()
          options.iterationCount = 0
  
          measure(options: options) {
              print(&quot;\n\nTEST ITERATION&quot;)
              handler.receivedFiles(files: testData)
  
          }
      }
  
  }
  </code></pre>
  <p>I suppose there is some XCTest feature that I'm not aware of but I can't wrap my head around what to search for in order to find something I can adapt.</p>