Verileri düzenlerken çok hantal nasıl test edilir?


19

Bir ayrıştırıcı yazıyorum ve bunun bir parçası olarak, Expandertek bir karmaşık deyimi birden çok basit ifadeye "genişleten" bir sınıf var. Örneğin, bunu genişletir:

x = 2 + 3 * a

içine:

tmp1 = 3 * a
x = 2 + tmp1

Şimdi bu sınıfı nasıl test edeceğimizi, özellikle testleri nasıl düzenleyeceğimizi düşünüyorum. El ile giriş sözdizimi ağacı oluşturabilir:

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

Veya ben bir dize olarak yazmak ve ayrıştırmak olabilir:

var input = new Parser().ParseStatement("x = 2 + 3 * a");

İkinci seçenek çok daha basit, daha kısa ve okunabilir. Ama aynı zamanda bir bağımlılık da getiriyor Parser, bu da bir hatanın Parserbu testte başarısız olabileceği anlamına geliyor . Yani, deney bir birim test olmayı bırak ediyorum Expanderve ben teknik olarak bir entegrasyon testi haline gelir tahmin Parserve Expander.

Sorum şu: Bu Expandersınıfı test etmek için bu tür entegrasyon testlerine çoğunlukla (veya tamamen) güvenmek doğru mu?


3
ParserEğer alışkanlık olarak sadece sıfır hata yaparsanız, bir hata başka bir test başarısız olabilir, aksine daha fazla kapsama sahip olduğu anlamına gelir Parser. Ne hakkında oldukça endişe ediyorum bir hata başarısız olması gerektiğindeParser bu test başarılı olabilir . Sonuçta, birim testleri hataları bulmak için vardır - bir test olmadığı halde olması gerekir.
Jonas Kölker

Yanıtlar:


27

Kendinizi basitçe yapabiliyorsanız, çok daha karmaşık, ilginç ve faydalı davranışlar içeren çok daha fazla test yazarken bulacaksınız. Yani bu seçenek

var input = new Parser().ParseStatement("x = 2 + 3 * a");

oldukça geçerli. Başka bir bileşene bağlıdır. Ancak her şey düzinelerce başka bileşene bağlıdır . Hayatının bir inç içinde bir şeyle alay ederseniz, muhtemelen birçok alaycı özelliğe ve test fikstürüne bağlısınız.

Geliştiriciler bazen herhangi bir modül, entegrasyon, stres veya diğer testler olmaksızın , birim testlerinin saflığına veya sadece birim testler ve birim testleri geliştirmeye aşırı odaklanırlar . Tüm bu formlar geçerli ve kullanışlıdır ve hepsi sadece Q / A veya boru hattının ilerisindeki operasyon personeli için değil, geliştiricilerin uygun sorumluluğudur.

Kullandığım yaklaşımlardan biri, bu yüksek seviye çalışmalarla başlamak, daha sonra testin uzun biçimli, en düşük ortak payda ifadesini oluşturmak için bunlardan üretilen verileri kullanmaktır. Örneğin, veri yapısını inputyukarıda üretilenlerden döktüğünüzde, aşağıdakileri kolayca oluşturabilirsiniz:

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

en düşük seviyede test eden bir çeşit test. Bu şekilde güzel bir karışım elde edersiniz: Bir avuç en temel, ilkel testlerden (saf birim testler), ancak bu ilkel seviyede bir hafta yazma testleri yapmadınız. Bu, Parserbir yardımcı olarak kullanarak daha fazla, biraz daha az atomik test yazmak için gereken zaman kaynağını verir . Sonuç: Daha fazla test, daha fazla kapsama alanı, daha fazla köşe ve diğer ilginç durumlar, daha iyi kod ve daha yüksek kalite güvencesi.


2
Bu mantıklı - özellikle her şeyin başkalarına bağlı olduğu gerçeğiyle ilgili. İyi bir birim testi mümkün olan minimum değeri test etmelidir. Mümkün olan en düşük miktar dahilindeki her şey, bir önceki birim testi ile test edilmelidir. Parser'ı tamamen test ettiyseniz, ParseStatement'ı test etmek için Parser'ı güvenle kullanabileceğinizi varsayabilirsiniz
Jon Story

6
Temel saflık endişesi (bence) birim testlerinize dairesel bağımlılıklar yazmaktan kaçınmaktır. Ayrıştırıcı veya ayrıştırıcı testleri ya genişletmesi ve bu genişletici testi ayrıştırıcı çalışma dayanıyorsa, o zaman sahip bir zor yönetmek tüm sen test ayrıştırıcı ve genişletici olmasıdır riskini tutarlı oysa ne yapmak istediniz, genişleticinin gerçekte olması gerekeni yaptığını test etmekti . Ancak, başka bir şekilde bağımlılık olmadığı sürece, bu birim testinde ayrıştırıcıyı kullanmak, birim testinde standart bir kitaplık kullanmaktan gerçekten farklı değildir.
Steve Jessop

@SteveJessop İyi bir nokta. Bağımsız bileşenler kullanmak önemlidir .
Jonathan Eunice

3
Ayrıştırıcının kendisinin pahalı bir işlem olduğu durumlarda yaptığım bir şey (örneğin, ex interop ile Excel dosyalarından veri okumak) ayrıştırıcıyı çalıştıran test oluşturma yöntemleri yazmak ve ayrıştırıcı dönüş veri yapısını yeniden oluşturmak . Daha sonra çıktıyı jeneratörden daha geleneksel birim testlerine kopyalarım. Bu, ayrıştırıcının yalnızca testler her çalıştırıldıklarında oluşturulmadığında doğru şekilde çalışması gerektiği için çapraz bağımlılığın azaltılmasına izin verir. (Excel işlemlerini oluşturmak / yok etmek için birkaç saniye / test harcamak güzel bir bonus oldu.)
Dan Neely

@ DanNeely'nin yaklaşımı için +1. Yeni kodun eski verilerle çalışabileceğinden emin olabilmemiz için veri modelimizin birkaç serileştirilmiş sürümünü test verisi olarak saklamak için benzer bir şey kullanıyoruz.
Chris Hayes

6

Tabii ki sorun değil!

Her zaman tam kod yolunu kullanan fonksiyonel / entegrasyon testine ihtiyacınız vardır. Ve bu durumda tam kod yolu, oluşturulan kodun değerlendirilmesini de içerir. Yani bu ayrıştırma test etmek olduğunu x = 2 + 3 * aile çalıştırmak eğer o kodu üretir a = 5irade seti xiçin 17birlikte çalışma ve eğer a = -2belirleyecektir xiçin -4.

Bunun altında , kodda hata ayıklamaya yardımcı olduğu sürece daha küçük bitler için birim testleri yapmalısınız . İçinizdeki daha ince taneli testler, koddaki herhangi bir değişikliğin testi de değiştirmesi gerekeceği olasılığı daha yüksektir, çünkü dahili arayüz değişir. Böyle bir testin uzun vadeli değeri azdır ve bakım işi ekler. Yani azalan getiriler var ve ondan önce durmalısın.


4

Birim testleri, kırılan belirli kodları ve kodun neresinde kırıldığını tespit etmenizi sağlar. Bu yüzden çok ince taneli testler için iyidirler. İyi birim testleri hata ayıklama süresini azaltmaya yardımcı olacaktır.

Ancak, deneyimimden birim testleri, doğru çalışmayı gerçekten doğrulamak için nadiren yeterince iyi. Bu nedenle entegrasyon testleri, bir zinciri veya işlem sırasını doğrulamak için de yararlıdır. Entegrasyon testleri, fonksiyonel testlerle yolunuzun bir parçası olur. Yine de belirttiğiniz gibi, entegrasyon testlerinin karmaşıklığı nedeniyle, testin koptuğu kodda belirli bir noktayı bulmak daha zordur. Ayrıca, zincirin herhangi bir yerindeki arızaların testin başarısız olmasına neden olacağı için biraz daha kırılganlığa sahiptir. Bununla birlikte, üretim zincirinde bu zincire sahip olmaya devam edersiniz, bu nedenle gerçek zinciri test etmek yine de yardımcı olur.

İdeal olarak, her ikisine de sahip olursunuz, ancak her halükarda, genellikle otomatik bir teste sahip olmak, test etmekten daha iyidir.


0

Ayrıştırıcı üzerinde çok sayıda test yapın ve ayrıştırıcı testleri geçerken, ayrıştırıcıyı taklit etmek ve diğer bileşeni test etmek için bu çıktıları bir dosyaya kaydedin.

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.