Hello. I will with to do performance testing on my swift code for an internship.
I have never done that, before, so my problem could be related to principle of performance testing.
I think I understand the principale of "self.measure" blocks and why it is necessary to execute
the code several hundreds of times.
My first problem is at the beginning, I tempt to do my tests, without pass to "setUp" and "tearDown" functions,
but searching on the Web, I have found it is better to use them, donc I change several things :
<code>
import XCTest
@testable import DernierTest
class PerformanceTests: XCTestCase {
let viewController = ViewController()
let secondViewController = SecondViewController()
let thirdViewController = ThirdViewController()
let fourthViewController = FourthViewController()
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func test_displayFamiliesTask() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.viewController.displayFamiliesTask { (success, response, error) in
if error != nil {
print(error)
return
}
if success {
guard let datas = response as? [AnyObject] else { return }
self?.viewController.displayFamilies(datas: datas)
}
}
}
}
}
func test_displayCategoriesTask() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.viewController.displayCategoriesTask { (success, response, error) in
if success {
guard let datas = response as? [Category] else { return }
DispatchQueue.main.async {
self?.secondViewController.collectionView.reloadData()
}
}
else if let error = error {
print(error)
}
}
}
}
}
func test_getAPITokenTask() {
self.measure { [weak self] in
for _ in 0…1000 {
_ = self.thirdViewController.getAPITokenTask()
}
}
}
func test_getTagsProductTask() {
self.measure { [weak self] in
for _ in 0...000 {
_ = self.thirdViewController.getTagsProductTask()
}
}
}
func test_searchTags() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.thirdViewController.searchByTag(token: )
}
}
}
func test_getFormattedTimestamp() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.thirdViewController.getFormatedTimestamp()
}
}
}
func test_fillFamilies() {
self.measure { [weak self] in
for _ in 0...1000 {
guard let filePath = Bundle.main.path(forResource: "families”, ofType: “json”),
let fileSource = try? String(contentsOfFile: filePath) else { return }
_ = self?.viewController.fillFamilies(json: fileSource as? AnyObject)
}
}
}
func test_parseJSON() {
self.measure { [weak self] in
for _ in 0...1000 {
guard let filePath = Bundle.main.path(forResource: "results”, ofType: “json”),
let fileSource = try? String(contentsOfFile: filePath) else { return }
_ = self.thirdViewController.parseJSON(json: fileSource as? AnyObject)
}
}
}
func test_fillTags() {
self.measure { [weak self] in
for _ in 0…1000 {
guard let filePath = Bundle.main.path(forResource: “families”, ofType: “json”),
let fileSource = try? String(contentsOfFile: filePath) else { return }
_ = self.thirdViewController.fillTags(json: fileSource as? AnyObject)
}
}
}
func test_FirstControllerCollectionViewNumberOfItemsInSection() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.viewController.collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int)
}
}
}
func test_FirstControllerCollectionViewCellForItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.viewController.collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
}
}
}
func test_FirstControllerCollectionViewDidSelectItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.viewController.collectionView(_, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}
}
}
func test_SecondControllerCollectionViewNumberOfItemsInSection() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.secondViewController.collectionView(_, collectionView: UICollectionView, numberOfItemsInSection section: Int)
}
}
}
func test_SecondControllerCollectionViewCellForItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.secondViewController.collectionView(_, collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
}
}
}
func test_SecondControllerCollectionViewDidSelectItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.secondViewController.collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}
}
}
func test_ThirdControllerCollectionViewNumberOfItemsInSection() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.thirdViewController.collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int)
}
}
}
func test_ThirdControllerCollectionViewCellForItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.thirdViewController.collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
}
}
}
func test_ThirdControllerCollectionViewDidSelectItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self.thirdViewController.collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}
}
}
}
Other problems are arrived, but until here, compiler did not return warning at least.
After that, I found it is better to use setUp and tearDown and I change my code like that :
import XCTest
@testable import DernierTest
class PerformanceTests: XCTestCase {
var viewController: UIViewController!
var secondViewController: UIViewController!
var thirdViewController: UIViewController!
var fourthViewController: UIViewController!
override func setUp() {
super.setUp()
viewController = ViewController()
secondViewController = SecondViewController()
thirdViewController = ThirdViewController()
fourthViewController = FourthViewController()
}
override func tearDown() {
viewController = nil
secondViewController = nil
thirdViewController = nil
fourthViewController = nil
super.tearDown()
}
func test_displayFamiliesTask() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.viewController.displayFamiliesTask { (success, response, error) in
if error != nil {
print(error)
return
}
if success {
guard let datas = response as? [AnyObject] else { return }
self?.viewController.displayFamilies(datas: datas)
}
}
}
}
}
func test_displayCategoriesTask() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.viewController.displayCategoriesTask { (success, response, error) in
if success {
guard let datas = response as? [Category] else { return }
DispatchQueue.main.async {
self?.secondViewController.collectionView.reloadData()
}
}
else if let error = error {
print(error)
}
}
}
}
}
func test_getAPITokenTask() {
self.measure { [weak self] in
for _ in 0…1000 {
_ = self?.thirdViewController.getAPITokenTask()
}
}
}
func test_getTagsProductTask() {
self.measure { [weak self] in
for _ in 0...000 {
_ = self?.thirdViewController.getTagsProductTask()
}
}
}
func test_searchTags() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.thirdViewController.searchByTag(token: )
}
}
}
func test_getFormattedTimestamp() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.thirdViewController.getFormatedTimestamp()
}
}
}
func test_fillFamilies() {
self.measure { [weak self] in
for _ in 0...1000 {
guard let filePath = Bundle.main.path(forResource: "families”, ofType: “json”),
let fileSource = try? String(contentsOfFile: filePath) else { return }
_ = self?.viewController.fillFamilies(json: fileSource as? AnyObject)
}
}
}
func test_parseJSON() {
self.measure { [weak self] in
for _ in 0...1000 {
guard let filePath = Bundle.main.path(forResource: "results”, ofType: “json”),
let fileSource = try? String(contentsOfFile: filePath) else { return }
_ = self?.thirdViewController.parseJSON(json: fileSource as? AnyObject)
}
}
}
func test_fillTags() {
self.measure { [weak self] in
for _ in 0…1000 {
guard let filePath = Bundle.main.path(forResource: “families”, ofType: “json”),
let fileSource = try? String(contentsOfFile: filePath) else { return }
_ = self?.thirdViewController.fillTags(json: fileSource as? AnyObject)
}
}
}
func test_FirstControllerCollectionViewNumberOfItemsInSection() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.viewController.collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int)
}
}
}
func test_FirstControllerCollectionViewCellForItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.viewController.collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
}
}
}
func test_FirstControllerCollectionViewDidSelectItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.viewController.collectionView(_, collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}
}
}
func test_SecondControllerCollectionViewNumberOfItemsInSection() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.secondViewController.collectionView(_, collectionView: UICollectionView, numberOfItemsInSection section: Int)
}
}
}
func test_SecondControllerCollectionViewCellForItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.secondViewController.collectionView(_, collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
}
}
}
func test_SecondControllerCollectionViewDidSelectItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.secondViewController.collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}
}
}
func test_ThirdControllerCollectionViewNumberOfItemsInSection() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.thirdViewController.collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int)
}
}
}
func test_ThirdControllerCollectionViewCellForItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.thirdViewController.collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
}
}
}
func test_ThirdControllerCollectionViewDidSelectItemAt() {
self.measure { [weak self] in
for _ in 0...1000 {
_ = self?.thirdViewController.collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
}
}
}
}
The compiler send back me warnings for every functions, saying it doesn't find the function in my ViewController, like that :
"Value of type 'UIViewController' has no member 'displayFamiliesTask'"
My first question is where can come these messages, have I need to use "setUp" and "tearDown",
or is it better to do without.
My second question concerns the closures. Is it possible to do a test on a closure, particularly an escaping closure, simply like that, or have I need to use a particular way.