Anonim ad alanları kodu test edilemez kılar


12

İşte tipik bir C ++ kodu:

foo.hpp

#pragma once

class Foo {
public:
  void f();
  void g();
  ...
};

foo.cpp

#include "foo.hpp"

namespace {
    const int kUpperX = 111;
    const int kAlternativeX = 222;

    bool match(int x) {
      return x < kUpperX || x == kAlternativeX;
    }
} // namespace

void Foo::f() {
  ...
  if (match(x)) return;
  ...

İyi bir deyimsel C ++ kodu gibi görünüyor - bir sınıf, matchyöntemler tarafından kullanılan bir yardımcı fonksiyon Foo, o yardımcı fonksiyon için bazı sabitler.

Ve sonra testler yazmak istiyorum.
Bunun için ayrı bir birim testi yazmak mükemmel bir mantıklı olacaktır match, çünkü oldukça önemsiz değildir.
Ancak anonim bir ad alanında bulunur.
Tabii ki bir test yazabilirim Foo::f(). Bununla birlikte Foo, ağır ve karmaşıksa iyi bir test olmayacaktır , bu test testçiyi diğer ilgisiz faktörlerden izole etmeyecektir.

Bu yüzden matchanonim ad alanından başka her şeyi taşımak zorundayım .

Soru: İşlevleri ve sabitleri anonim ad alanına yerleştirmenin amacı nedir, eğer onları testlerde kullanılamaz hale getirirse?


3
@ BЈовић kodu yeniden okuyun - anonim ad alanı foo.cppüstbilgide değil! OP, anon ad alanlarını bir başlığa koymamanız gerektiğini gayet iyi biliyor gibi görünüyor.
amon

Adsız Bir Ad Alanında C ++ Kodunu Test Etme konusunda bir fikir ... ama "nokta", kapsüllemenin iyi olmasıdır. Sonuçta, özel üye işlevleriyle ilgili aynı sorun var: bunlar güvenilir olmayan bir şekilde test edilemez, ancak birim testi için gizleme bilgisinden vazgeçmek istemezsiniz (örn. Stackoverflow.com/a/3676680/3235496 ).
manlio

1
Sizin durumunuz kavramsal olarak özel yöntemleri test etme (veya test etmeme) durumundan çok farklı değildir. Dolayısıyla, burada Programcılar'da "birim testi özel" için arama yaptığınızda, doğrudan davanıza uygulayabileceğiniz birçok yanıt alırsınız.
Doc Brown

@DocBrown Anonim fonksiyonların nasıl test edileceğini sormuyorum. ad. "Neden anon .namepaces içine kod koymak?" (sorunun sonundaki metne bakın). Başlığı farklı bir şeye değiştirmek için Ixrec'i suçlayın.
Abyx

2
@Abyx: yukarıda bahsettiğim diğer cevaplarda, özel yöntemleri test etmenin gerçekten kötü bir fikir olduğu ve friendanahtar kelimeyi bu amaçla kötüye kullanmanın önerilmediği konusunda birçok uzmanın büyük bir fikir birliği bulacaksınız . bir yöntem kısıtlaması, artık doğrudan test edemeyeceğiniz bir duruma yol açarsa, bu özel yöntemlerin yararlı olmadığını gösterir.
Doc Brown

Yanıtlar:


7

Özel uygulama ayrıntılarını birim olarak sınamak istiyorsanız, adsız ad alanları için özel (veya korumalı) sınıf üyeleriyle aynı türden kaçma işlemini gerçekleştirirsiniz:

İçeri gir ve parti yap.

Kötüye kullandığınız sınıflar friendiçin, adsız ad alanları için #include-mekanizmi kötüye kullanırsınız, bu da sizi kodu değiştirmeye bile zorlamaz.
Artık test kodunuz (veya her şeyi ortaya çıkaracak bir şey daha iyi) aynı TU'da olduğuna göre, sorun yok.

Dikkat edilmesi gereken bir nokta: Uygulama ayrıntılarını test ederseniz, bunlar değişirse testiniz kesilir. Sadece yine de sızacak uygulama ayrıntılarını test ettiğinizden emin olun veya testinizin olağandışı geçici olduğunu kabul edin.


6

Örneğinizdeki işlev oldukça karmaşık görünüyor ve birim testi için başlığa taşımak daha iyi olabilir.

işlevleri ve sabitleri anonim ad alanına yerleştirmenin amacı nedir, eğer onları testlerde kullanılamaz hale getirirse?

Onları dünyanın geri kalanından izole etmek. Ve sadece isim ve isim alanına koyabileceğiniz fonksiyonlar ve sabitler değil, aynı zamanda tipler içindir.

Ancak, birim testlerinizi çok karmaşık hale getirirse, yanlış yapıyorsunuz demektir. Bu durumda işlev oraya ait değildir. Daha sonra, testi daha basit hale getirmek için biraz yeniden düzenleme yapmanın zamanı geldi.

Bu nedenle, anonim ad alanında bazen çok basit işlevlere, bazen o çeviri biriminde kullanılan sabitlere ve türlere (typedefs dahil) gitmeniz gerekir.


5

Maç için ayrı bir birim testi yazmak mükemmel bir mantıklı olacaktır, çünkü oldukça önemsizdir.

Gösterdiğiniz kod match, herhangi bir zor kenar durumu olmayan oldukça önemsiz bir 1 astar mı yoksa basitleştirilmiş bir örnek gibi mi? Her neyse, bunun basitleştirilmiş olduğunu varsayacağım ...

Soru: Testlerde kullanılmaz hale getirirse, fonksiyonları ve sabitleri anonim ad alanına koymanın anlamı nedir?

Bu soru beni buraya atlatmak istediğim şeydi, çünkü Deduplicator zaten #includehile yapmak ve hile yoluyla erişmek için mükemmel bir yol gösterdi . Ancak buradaki ifade, her bir iç uygulama detayını test etmek gibi geliyor, her şeyin evrensel son hedefi, ondan uzak olduğunda.

Birim testinin bile hedefi her zaman küçük tanecikli dahili mikro birimi işlevselliğini test etmek değildir. Geliştiricilerin kullandıkları neden aynı soru sorarak bile cevap soru zorlaştırabilir C. You statik dosya kapsamı fonksiyonlar için de geçerlidir pimplsgerektirecek C ++ hem friendship ve #includegeliştirilmiş derleme süreleri için uygulama ayrıntıları kolay test edilebilir bir işlem, beyaz kutu için hile, Örneğin

Bir tür pragmatik perspektiften, kulağa kaba matchgelebilir, ancak açılmasına neden olan bazı kenar durumlarda doğru bir şekilde uygulanamayabilir. Bununla birlikte, Fooerişime sahip olan tek dış sınıf, matchonu bu uç durumlarla karşılaşacak şekilde kullanamazsa, o zaman değişiklikler olmadan karşılaşılmayacak olan bu uç durumlara sahip olanın doğruluğu ile Fooilgili değildir match, bu Foonoktada testleri Foobaşarısız olacak ve hemen öğreneceğiz.

Her bir iç uygulama detayını (belki de kritik bir yazılım, örneğin) test etmek için istekli daha saplantılı bir zihniyet devreye girebilir ve parti yapabilir, ancak birçok insan bunun en iyi fikir olduğunu düşünmez. akıl almaz en kırılgan testler. YMMV. Ama ben sadece bu tür uber-ince taneli-iç-detay-seviye test edilebilirlik gibi bir kulağa neden olan bu soruya değinmek istedim, en zorlu birim test zihniyeti bile burada biraz rahatlayabilir ve her sınıfın içini röntgenden uzak tutmak

Peki neden insanlar C ++ 'da anonim ad alanlarında veya dış dünyadan gizlenmiş C'de dahili bağlantıya sahip dosya kapsamındaki statik işlevler olarak işlevler tanımlıyor? Ve esas olarak bu: onları dış dünyadan gizlemek. Bunun, derleme sürelerini azaltmadan karmaşıklığı azaltmaya (başka bir yerde erişilemeyen başka yerlerde sorunlara neden olamaz) ve bunun gibi çeşitli etkileri vardır. Muhtemelen özel / dahili uygulama detaylarının test edilebilirliği, insanların yaptıklarında, örneğin inşa sürelerini kısaltmak ve dış dünyadan gereksiz karmaşıklığı gizlemek için akıllarında bir numaralı şey değildir.


Keşke bunu on kere yükseltebilseydim. Kritik, yüksek güvence yazılımıyla ilgili bir teğet olarak, ayrıntıların doğruluğu ile çok daha fazla ilgileniyorsunuz. C ++ için bu deyimsel stil bunun için uygun değildir. Anonim ad alanları veya proxy benzeri desenler gibi dilin özelliklerini kullanmam. Sınırımı [desteklenen] kullanıcı alanı üstbilgileri ve [desteklenmeyen] geliştirici alanı üstbilgileri ile kabaca kontrol ederdim.
David
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.