Birim test kaynak modelleri


10

Özel uzantımda yalnızca öğelerimin ekleme / düzenleme formundaki bazı seçimleri ve / veya çoklu seçimleri doldurma amacına hizmet eden birkaç modelim var.
Magento'nun "kaynak modeller" dediği şey budur.
İlgili değerler her zaman aynıdır ve yöntemler aynı şeyi döndürür.
Bunları nasıl test etmeliyim? Ya da daha iyisi, onlar için birim testleri yazmalı mıyım?
İşte bir örnek.
Aşağıdaki sınıf, typeaynı alanın ızgara sütunu olarak adlandırılan bir alan için form eklemek / düzenlemek için kullanılır .

<?php
namespace Sample\News\Model\Author\Source;

use Magento\Framework\Option\ArrayInterface;

class Type implements ArrayInterface
{
    const COLLABORATOR = 1;
    const EMPLOYEE = 2;

    /**
     * Get options
     *
     * @return array
     */
    public function toOptionArray()
    {
        $_options = [
            [
                'value' => '',
                'label' => ''
            ],
            [
                'value' => self::COLLABORATOR,
                'label' => __('Collaborator')
            ],
            [
                'value' => self::EMPLOYEE,
                'label' => __('Employee')
            ],
        ];
        return $_options;
    }

    /**
     * get options as key value pair
     *
     * @return array
     */
    public function getOptions()
    {
        $_tmpOptions = $this->toOptionArray();
        $_options = [];
        foreach ($_tmpOptions as $option) {
            $_options[$option['value']] = $option['label'];
        }
        return $_options;
    }
}

Yanıtlar:


15

Bu harika bir iş parçacığı ve @KAndy ve @fschmengler gelen cevapları gerçekten çok seviyorum.
"X'i test etmeli miyim?" Gibi bir soru sorduğumda değerli bulduğum bazı ek düşünceler eklemek istiyorum. veya "X'i nasıl test etmeliyim?".

Ne ters gidebilir ki?

  • Aptal bir yazım hatası yapabilirim (her zaman olur)
    Bu genellikle bir test yazmayı haklı çıkarmaz.
  • İhtiyacım olan kodu çekirdekten mi yoksa farklı bir modülden mi kopyalayıp ihtiyaçlarıma göre ayarlayacağım mı?
    Bunu yapmak için çok tehlikeli bir şey olduğunu düşünüyorum, bu genellikle ince böcekler bırakır. Bu durumda, çok pahalı değilse bir test yazmayı tercih ederim. Kaynak modelleri yapılandırmasını temel almak aslında onları daha riskli IMO yapar.
  • Farklı bir modülle çakışma olabilir mi?
    Bu neredeyse sadece yapılandırma kodu için geçerlidir. Böyle bir durumda bana bunun ne zaman gerçekleştiğini söyleyen bir entegrasyon testi yaptırmayı severim.
  • Magento, gelecekteki bir sürümde API'yı değiştirebilir mi?
    Bu durumda çok olası değildir, çünkü kodunuz sadece bir arayüze bağlıdır. Ancak daha somut sınıflar söz konusuysa veya kodum çekirdek bir sınıfı genişletirse, bu potansiyel bir risk haline gelir.
  • Yeni bir PHP sürümü kodumu kırabilir. Ya da belki gelecek yıllarda PHP 5.6'yı desteklemek istiyorum.
    Yine, burada pek olası değil, ancak bazı durumlarda beni uyarmak için bir test istiyorum, gelecekte uyumsuz sözdizimi kullanmak için kodu değiştirmem gerekir.

Kodu test etmek ne kadar pahalı?

Bunun iki yönü vardır:

  • Test yazmak için gereken çaba ve zaman
  • Manuel olarak yazmak üzereyim kod parçasını test etmek için çaba ve zaman miktarı.

Bazı kod parçasının geliştirilmesi sırasında, ben bunu düşününceye kadar oldukça sık yazıyorum kodunu çalıştırmak zorunda eğilimindedir. Bu bir birim testle elbette çok daha kolay.

Sizin durumunuzda bir test yazmak ölü ucuzdur. Fazla zaman ve çaba gerektirmez. @KAndy, tüm kodların korunması gerektiği konusunda haklıdır, ancak daha sonra tüm testlerin saklanması gerekmez.
Bu, sadece aptalca bir hata yapmadığımı kontrol etmek ve daha sonra sınıf bittikten sonra silmek için bir birim testi yazacağım bir örnek olabilir. Bir test uzun vadeli değer sağlamazsa, bunları silmenin mantıklı olduğunu düşünüyorum.

Bu soru ayrıca yazılacak test türünün seçilmesi açısından da önemlidir: örneğin birim veya entegrasyon.

Yazdığım kod ne kadar değerli?

Yazdığım bir kod parçası bir modülün sağladığı hizmet için gerekliyse, ne kadar önemsiz olduğuna bakılmaksızın test ediyorum.
Sadece küçük bir yardımcı yöntemse, örneğin UI odaklı ve iş mantığının bir parçası değilse, belki de değil.

Kodun değiştirilmesi gerekecek mi?

Zamanla, test kapsamına sahip olmaya çok alıştım, ortaya çıkarılan kodu değiştirmek çok güvensiz geliyor. Bu, kaynak modele bir seçenek eklemek gibi çok basit şeylerin yanı sıra, sınıfı farklı bir klasöre / ad alanına taşımak veya bir yöntemi yeniden adlandırmak gibi şeyleri de içerir.
Bu tür değişiklikler için testlerin yaptırılması paha biçilmezdir.

Belgelere ihtiyacı var mı?

Kodu kullanmak ne kadar zor? Örneğin, bu önemsizdir, ancak bazı daha karmaşık durumlarda, bir teste sahip olmak, diğer geliştiriciler (veya birkaç ay içinde kendim) için dokümantasyon amacıyla harikadır.

Keşif ve Öğrenme

Bazı kod üzerinde çalışıyorum ve nasıl test emin değilim , ben bir test yazmak çok değerli buluyorum. Süreç neredeyse her zaman bana neyle uğraştığımı daha iyi anlıyor.
Bu özellikle kendilerini test etmeyi öğrenen geliştiriciler için geçerlidir.
Bu, daha sonra testi silmenin mantıklı olabileceği bir örnektir, çünkü sağladığı ana değer öğrenmekti.

Disiplin ve Stres

Kırmızı-yeşil-refactor döngüsüne yapışmak hızlı gitmeme yardımcı oluyor. Bu özellikle baskı altında geçerlidir. Bu nedenle, bir kod parçası gerçekten teste layık olmasa bile, özellikle kodun test edilmesi önemsizse, TDD'yi takip edebilirim.
Bu beni akışta ve uyanık tutuyor.

Ne ve nasıl test edilir?

Ayrıca, testi çok farklı bir ayrıntı düzeyinde yazabileceğinizi düşünün.

  • Kesin dönüş değerinin test edilmesi.
    Bu, her değişikliğe göre ayarlanması gereken çok katı bir test olacaktır. Örneğin, dönüş dizisindeki öğelerin sırası değişirse, testin kesilmesini ister misiniz?
  • Dönüş değerinin yapısının test edilmesi.
    Kaynak model için bu, her alt diziyi biri a labelve diğeri valueanahtarlı olmak üzere iki kayıt olarak kontrol ediyor olabilir .
  • Sınıf kontrolü yapılır ArrayInterface.
  • Sınıfı test etmek, getOptions()bu yöntem uygulanan arabirimin bir parçası olmasa bile sağlar.

Test edilebilen her olası şey için değeri, sürdürülebilirliği ve maliyeti göz önünde bulundurun.

özet

Özetlemek gerekirse: bir kod parçasının test edilmesi gerekip gerekmediği sorusunun tek bir cevabı yoktur. Yanıt, koşullara bağlı olarak her geliştirici için farklı olacaktır.


2
Mükemmel cevap! "Artık değer sağlamadıklarında testleri sil" bölümünü vurgulamak istiyorum - bazen ilk geliştirici sırasında yardımcı olan eski testler sadece uzun vadede yol alıyor.
Fabian Schmengler

1
Şüphe duyduğum 2 soruyu daha cevapladınız. teşekkür ederim
Marius

6

Kanımca, "kaynak modeller için birim testleri yazma, evet ya da hayır" diye genel bir cevap yoktur.

Kaynak modeller için birim testleri yazdım, ancak bunlar harici verileri getiren dinamik kaynak modellerdi ve orada mantıklı.

Yüceltilmiş dizilerden başka bir şey olmayan kaynak modeller için (örneğin örnekte olduğu gibi), birim testleri yazmaya zahmet etmem. Ancak bir şekilde, bir hata yapmadığınızdan emin olmanız gerekir. Birkaç seçenek vardır:

  1. ünite testi
  2. entegrasyon testi
  3. yapılandırmaya manuel olarak bak

TDD'yi takip ediyor musunuz? Ardından (1) ve (2) arasından veya her ikisinden birini seçin. Aksi takdirde, (2) ve (3) arasından seçim yapın.


Sistem yapılandırma seçenekleri için kaynak modelleri kullanırsanız, bir tümleştirme testi (tüm yapılandırma seçenekleriniz için bir test) yapılandırma bölümünü oluşturabilir ve <select>öğelerin mevcut olup olmadığını ve beklenen değerleri içerdiğini kontrol edebilir . Bunun belirli bir sınıfı test etmekle değil, her şeyin doğru bir şekilde bağlandığını test etmekle ilgili olduğunu unutmayın.


@KAndy'nin dediği gibi, ideal olarak o kadar büyük bir levhaya ihtiyacınız yoktur, sadece birim test edilmiş bir taban sınıfını genişletin ve bir özelliği geçersiz kılın veya harici yapılandırmadaki değerleri tanımlayın.

Bu senaryoda, somut uygulamalar için birim testler herhangi bir ek değer sağlamaz. Bu sınıfların çoğuna sahipseniz, ArraySourceMagento tarafından sağlanmadığı sürece kendinize bir temel sınıf yazmak iyi bir fikir olabilir .


Böyle bir temel sınıfla, kaynak modeliniz şöyle görünebilir:

class Type extends ArraySource
{
    const COLLABORATOR = 1;
    const EMPLOYEE = 2;
    protected $elements = [
        self::COLLABORATOR => 'Collaborator',
        self::EMPLOYEE     => 'Employee',
    ];
    protected $withEmpty = true;
    protected $translate = true;
}

Onay için teşekkürler. Yüceltilmiş dizilerimi yapılandırılabilir bir seçenek listesine dönüştürmeye çalışacağım, ancak tam olarak N seçeneğine sahip modeller için de aynı şey geçerli mi? "Durum" kaynak modeli gibi.
Marius

Bir "durum" kaynak modelinin "yazar türü" örneğinizden nasıl farklı olacağını
görmüyorum

çünkü örneğin etkin varlıklara filtre uygulamak için ön uçta 0 ve 1 (sınıf sabitleri) değerlerini kullanabilirim. Bu durumda, seçenek değerlerinin arkasında mantık vardır. onlar sadece key=>valueçiftler değil .
Marius

Fakat bu mantık kaynak modelin bir parçası değil, değil mi? Bu, burada önemli olmadığı anlamına gelir. Başka yerlerde de kullanabileceğiniz sabitlere sahip olacaksınız. Böyle bir implentasyonu nasıl kullanacağımı gösteren bir örnek ekledim.
Fabian Schmengler

5

Bunları nasıl test etmeliyim?

Bence yapmamalısın.

Destek ve bakım maliyetini artırmak için sisteme kod ekleyin, ancak test süreci LEAN olmalıdır .

Bu kod üzerinde daha fazlası olmamalıdır. Magento'dan daha farklı yerlerde kullanılacak seçenek kümelerini tanımlamanın genel bir beyan yolu olması gerektiğine inanıyorum. Ve bu sınıf için sınav yazma isteğiniz bana kötü kod kokusu gösteriyor


1
Teşekkürler. Yani, bu seçeneklerin sabit olarak kodlanmaması, bir yapılandırma dosyasından gelmesi gerektiğini söylüyorsunuz (örneğin di.xml). Bunu yapabilirim. Ancak durum kaynağı modelleri için de aynı şey geçerli mi? Yani, yukarıdakiyle aynı sınıfa sahipsem, ancak yalnızca durum etkin ve devre dışı (1,0) ile aynı yapılandırma yaklaşımını kullanmalıyım? Evet ise, bunun benim için aşırı mühendislik gibi dikiş yaptığını söylemek istiyorum.
Marius
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.