奇怪的单位测试运行时间差异

时间:2017-03-22 20:03:07

标签: unit-testing mstest

我的单元测试方法完全相同:

    var app = angular.module('starter', ['ionic', 'ngCordova']);

app.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if (window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if (window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
});

app.controller('MapController', function($scope, $cordovaGeolocation, $ionicLoading, $ionicPlatform) {

  $ionicPlatform.ready(function() {

    $ionicLoading.show({
      template: '<ion-spinner icon="bubbles"></ion-spinner><br/>Acquiring location!'
    });

    var posOptions = {
      enableHighAccuracy: true,
      timeout: 20000,
      maximumAge: 0
    };

    $cordovaGeolocation.getCurrentPosition(posOptions).then(function(position) {
      var lat = position.coords.latitude;
      var long = position.coords.longitude;

      var myLatlng = new google.maps.LatLng(lat, long);

      var mapOptions = {
        center: myLatlng,
        zoom: 16,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      };

      var map = new google.maps.Map(document.getElementById("map"), mapOptions);

      $scope.map = map;
      $ionicLoading.hide();

    }, function(err) {
      $ionicLoading.hide();
      console.log(err);
    });
    google.maps.event.addListener($scope.map, 'idle', function() {

      var marker = new google.maps.Marker({
        map: $scope.map,
        position: new google.map.LatLng(myLatlng)
        icon:'http://i.imgur.com/fDUI8bZ.png'

      });

      var infoWindow = new google.maps.InfoWindow({
        content: "Here I am!"
      });

      google.maps.event.addListener(marker, 'click', function() {
        infoWindow.open(map, marker);
      });
      infowindow.open(map, marker);


    });
  })
});

其中一个总是在不同的时间内运行。

enter image description here

如果我删除第一个,void Test() { for (int i = 0; i < 100000; i++); } 总是不同的:

enter image description here

如果我添加其他测试方法,TestMethod3总是不同的:

enter image description here

总有一种方法与其他方法不同。 这种奇怪的差异背后的原因是什么?

我目前正在研究算法并尝试使用测试方法测量运行时间。这种差异让我想到测试方法的运行时间是否可靠。

2 个答案:

答案 0 :(得分:1)

这与visual studio中的测试运行器有关。测试通常同时进行,但是你看到的时间通常是首先启动的测试。我已经注意到在视觉工作室已有多年了。如果你自己运行其中一个,你会注意到它的运行时间比运行时的运行时间长。

我一直认为它与测试仍在加载时提前启动计时器有关。

答案 1 :(得分:0)

您无法在简单的单元测试中测试性能。部分原因是测试框架有许多不同的实现和配置,对测试的性能有不同的影响。

最值得注意的是测试是并行,多线程还是连续运行。显然,第一个选项完全使任何基准测试无效。但是,第二种选择仍然不能保证有效的基准测试。

这是因为其他因素与实际的单元测试框架无关:这些因素包括

  • 由于类加载和内存分配导致的初始延迟
  • 将您的字节代码即时编译为机器代码。这很难控制,而且看似无法预测。
  • 分支预测,可能会极大地影响您的运行时行为,具体取决于已处理数据和控制流的性质
  • 垃圾收集

在Java中做甚至远程有效的基准测试本身就是一种艺术形式。为了接近,你应该至少确保

  • 您正在一个线程中运行您感兴趣的代码,没有其他活动线程
  • 不要使用垃圾收集(即确保有足够的内存供测试在没有GC的情况下执行,并正确设置JVM的GC选项)
  • 有一个预热阶段,您可以在开始基准测试之前以足够的迭代次数运行代码。

这篇关于'Robust Java Benchmarking'的IBM文章有助于介绍Java基准测试的缺陷。