2015-09-01 12 views
5

Właśnie zaktualizowałem kilka projektów do wersji VS2015/C# 6.Wykluczanie właściwości automatycznych z zakresu kodu w Visual Studio 2015

Obecnie analiza zasięgu kodu MSTest zgłasza, że ​​niektóre właściwości automatyczne nie są uwzględniane w testach jednostkowych. Tak nie było w Visual Studio 2013 i podejrzewam, że może to mieć coś wspólnego z nowymi właściwościami autoproperty w C# 6.

Radzenie sobie ze wszystkimi fałszywymi pozytywami generuje raczej porażkę celu narzędzia Code Coverage, ponieważ praktycznie uniemożliwia zidentyfikowanie rzeczywistego kodu bez pokrycia testowego. Nie chcemy pisać testów jednostkowych dla wszystkich naszych DTO, a ja naprawdę nie musiałbym przechodzić przez projekt, opisując każdą pojedynczą właściwość automatyczną z ExcludeFromCodeCoverage.

Utworzyłem roboczą MCVE na https://github.com/iaingalloway/VisualStudioCodeCoverageIssue


  • Rozwinąć VisualStudio2013.sln w Visual Studio 2013 Premium lub Ultimate.
  • Kliknij przycisk Testuj -> Przeanalizuj zasięg kodu -> Wszystkie testy.
  • Należy zauważyć, że w oknie "Wyniki pokrycia kodu" zgłasza się 0 bloków "Nieobjęte".

  • Otwarte VisualStudio2015.sln w Visual Studio 2015 Enterprise.
  • Kliknij przycisk Testuj -> Przeanalizuj zasięg kodu -> Wszystkie testy.
  • Zauważ, że "Code Coverage Results" raportów okienne 1 Block "nieuregulowanych" (getter dla ExampleDto.Value)

Czy jest możliwe aby skonfigurować wbudowane narzędzie Code Coverage w Visual Studio 2015, aby zignorować właściwości automatyczne, takie jak Visual Studio 2013?

+0

Takie zachowanie wydaje się być błąd w Visual Studio 2015. Obecnie nie ma obejścia inne niż przy użyciu '[ ExcludeFromCodeCoverage] '. Możesz monitorować postęp biletu na: - https://connect.microsoft.com/VisualStudio/Feedback/Details/1742106 –

Odpowiedz

4

Jako obejście, można dodać następujące do pliku .runsettings: -

<RunSettings> 
    <DataCollectionRunSettings> 
    <DataCollector ...> 
     <Configuration> 
     <CodeCoverage> 
      <Functions> 
      <Exclude> 
       <Function>.*get_.*</Function> 
       <Function>.*set_.*</Function> 
      </Exclude> 
      ... 

To nie jest wielki obejście, ale tak długo, jak nie używasz żadnych funkcji z „get_” lub " set_ "w nazwach, które powinny dać ci zachowanie, którego potrzebujesz.

0

Myślę, że [ExcludeFromCodeCoverage] jest Twoją jedyną opcją. To tylko jednorazowa rzecz, którą musisz zrobić. Osobiście, piszę testy jednostkowe na getter/setter właściwości, szczególnie takie jak w WPF, gdzie chcę mieć pewność, że powiadomienia o zmianie właściwości.

+2

Jeśli masz logikę (np. Powiadomienia o zmianie właściwości) wewnątrz gettera/setera, to jest jedna rzecz .To zupełnie co innego, jeśli jest to tylko własność automatyczna. 'int Foo {get; zestaw; } '. W tej bazie kodu są ich tysiące. Prawie 18% "bloków" w analizie kodu, a kolejne dodawane za każdym razem. Tam * musi * być lepszym sposobem! –

+0

@Nie wydaje się, że nie ma żadnej możliwości z MSTest. Zobacz https://msdn.microsoft.com/en-us/library/jj159530.aspx, aby uzyskać szczegółowe informacje o tym, co można wykluczyć w VS2015. –

0

Nie podobało mi się filtrowanie wszystkich metod pobierania/ustawiania, szczególnie, że czasami piszę logikę pobierania i ustawiania, która musi zostać przetestowana. Dla mnie, tylko podstawową ochronę stosunkowo prostych modeli, co następuje parę testów xUnit pracował dobrze:

public class ModelsGetSetTest 
{ 

    [ClassData(typeof(ModelTestDataGenerator))] 
    [Theory] 
    public void GettersGetWithoutError<T>(T model) 
     where T: BaseEntity 
    { 
     PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     for (var i = 0; i < properties.Length; i++) 
     { 
      var prop = properties[i]; 
      prop.GetValue(model); 
     } 
    } 

    [ClassData(typeof(ModelTestDataGenerator))] 
    [Theory] 
    public void SettersSetWithoutError<T>(T model) 
     where T : BaseEntity 
    { 
     PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); 
     for (var i = 0; i < properties.Length; i++) 
     { 
      var prop = properties[i]; 
      prop.SetValue(model, null); 
     } 
    } 

    public class ModelTestDataGenerator : IEnumerable<object[]> 
    { 
     private readonly List<object[]> _data = new List<object[]> 
     { 
      new object[] { new UserRole() }, 
      new object[] { new User() }, 
      new object[] { new Role() } 
     }; 

     public IEnumerator<object[]> GetEnumerator() => _data.GetEnumerator(); 
     IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 
    } 
}