SORU
6 Aralık 2011, Salı


Nasıl Codeıgniter ile PHPUnit kullanırım?

Okuma ve PHPUnit, SimpleTest ve diğer Birim Test çerçeveler " başlıklı bir yazı okudum. Onlar çok büyük ses! Sonunda PHPUnit https://bitbucket.org/kenjis/my-ciunit/overview Codeıgniter sayesinde çalışıyor

Şimdi benim sorum, nasıl kullanırım?

Gördüğüm her öğretici soyut assertEquals(2, 1 1) gibi kullanın biraz ya

public function testSpeakWithParams()
{
    $hello = new SayHello('Marco');
    $this->assertEquals("Hello Marco!", $hello->speak());
}

Eğer bu tahmin edilebilir bir dize çıkış verecek bir fonksiyon olsaydı harika. Genellikle uygulamalarım veritabanındaki verileri bir grup daha sonra tablo bir çeşit görüntüler yakalayın. Nasıl Codeıgniter ... ... denetleyicileri test edebilirim?

Test Odaklı Geliştirme yapmak istiyorum ve PHPUnits öğretici sitesini okudum, ama bir kez daha örnek çok soyut gibi görünüyor. Codeıgniter benim işlevlerin çoğu veri görüntülüyorsunuz.

Bir kitap ya da pratik bir uygulama ve PHPUnit test örnekleri ile büyük bir eğitim var mı?

CEVAP
6 Aralık 2011, Salı


Öyle görünüyor ki anlamak temel yapısı/sözdizimi yazmayı testleri ve birim testleri Codeıgniter kod olmamalı farklı test non-CI kod, çok istiyorum odaklan temel endişeleri/sorunları ...

Benzer sorular çok uzun PHPUnit ile önce vardı. Resmi bir eğitimi olmayan biri olarak Birim Test zihniyet içine almak ve ilk başta soyut doğal görünüyordu buldum. Benim durumumda Bu ... için ana nedeni bence, ve muhtemelen çok daha kararlı değilseniz bu soru sanaGERÇEKTENçalışma kodu endişeleri şimdiye kadar ayrı.

Test iddialar metotların/fonksiyonların büyük olasılıkla birkaç farklı ayrı görevleri gerçekleştirmek için soyut gibi görünüyor. Başarılı bir test zihniyet kodunuzu düşünmek nasıl bir değişiklik gerektirir. "Çalışıyor mu?" konusunda başarıyı tanımlama bırakmalısın Sorman yerine, işe yarıyor", diğer kodu ile oynayacak, diğer uygulamalar için yararlı kılan bir şekilde tasarlanmıştır ve çalışır durumda olduğundan emin olabilir miyim?"

Örneğin, aşağıda muhtemelen bu noktaya kadar kod yazdım nasıl basitleştirilmiş bir örnektir:

function parse_remote_page_txt($type = 'index')
{
  $remote_file = ConfigSingleton::$config_remote_site . "$type.php";
  $local_file  = ConfigSingleton::$config_save_path;

  if ($txt = file_get_contents($remote_file)) {
    if ($values_i_want_to_save = preg_match('//', $text)) {
      if (file_exists($local_file)) {
        $fh = fopen($local_file, 'w ');
        fwrite($fh, $values_i_want_to_save);
        fclose($fh);
        return TRUE;
      } else {
        return FALSE;
      }
  } else {
    return FALSE;
  }  
}

Burada tam olarak ne olduğu önemli değil. Bu kodu test etmek zordur neden göstermek için çalışıyorum:

  • Tek bir yapılandırma sınıfı değerler üretmek için kullanıyor. Fonksiyon başarı tekil değerleri bağlıdır, ve nasıl bu işlev, farklı değerlerle yeni yapılandırma nesneleri oluşturmak zaman doğru tecritte çalıştığını test edebilir misiniz? Daha iyi bir seçenek fonksiyonlarını kontrol sahibi olan bir yapılandırma nesne ya da bir dizi oluşur $config bir argüman olabilir. Bu geniş "Dependency Injection" ve formül tarafından başlatılan. tüm bu teknik tartışmaları var denir

  • IF iç içe geçmiş ifadeler dikkat edin. Test test bir çeşit ile her satırı yürütülebilir kat ettiğiniz anlamına gelir. Sen if yuva, yeni bir test yolu gerektiren kod yeni şube yaratıyorsun.

  • Son olarak, yapıyor gibi görünüyor olsa da bu işlev, bir şey (uzak bir dosyanın içeriğini ayrıştırma) aslında birkaç görevleri gerçekleştirmek nasıl görüyorsunuz? Eğer gayretli endişelerinizi kodunuzu sonsuz olur Daha fazla ayrı test edilebilir. Daha test edilebilir bu aynı şeyi yapmak için bir yol olacaktır ...


class RemoteParser() {
  protected $local_path;
  protected $remote_path;
  protected $config;

  /**
   * Class constructor -- forces injection of $config object
   * @param ConfigObj $config
   */
  public function __construct(ConfigObj $config) {
    $this->config = $config;
  }

  /**
   * Setter for local_path property
   * @param string $filename
   */
  public function set_local_path($filename) {
    $file = filter_var($filename);
    $this->local_path = $this->config->local_path . "/$file.html";
  }

  /**
   * Setter for remote_path property
   * @param string $filename
   */
  public function set_remote_path($filename) {
    $file = filter_var($filename);
    $this->remote_path = $this->config->remote_site . "/$file.html";
  }

  /**
   * Retrieve the remote source
   * @return string Remote source text
   */
  public function get_remote_path_src() {
    if ( ! $this->remote_path) {
      throw new Exception("you didn't set the remote file yet!");
    }
    if ( ! $this->local_path) {
      throw new Exception("you didn't set the local file yet!");
    }
    if ( ! $remote_src = file_get_contents($this->remote_path)) {
      throw new Exception("we had a problem getting the remote file!");
    }

    return $remote_src;
  }

  /**
   * Parse a source string for the values we want
   * @param string $src
   * @return mixed Values array on success or bool(FALSE) on failure
   */
  public function parse_remote_src($src='') {
    $src = filter_validate($src);
    if (stristr($src, 'value_we_want_to_find')) {
      return array('val1', 'val2');
    } else {
      return FALSE;
    }
  }

  /**
   * Getter for remote file path property
   * @return string Remote path
   */
  public function get_remote_path() {
    return $this->remote_path;
  }

  /**
   * Getter for local file path property
   * @return string Local path
   */
  public function get_local_path() {
    return $this->local_path;
  }
}

Gördüğünüz gibi, bu sınıf yöntemlerin her biri kolayca test edilebilir bir sınıfın belirli bir işlevi gerçekleştirir. Uzak dosya alma işe yaradı mı? Ayrıştırmak için çalışıyorduk değerleri bulduk? Vb. Bir anda bütün o soyut iddialar çok daha yararlı görünüyor.

IMHO, sadece emin şey beklendiği gibi iş yapmak daha mantıklı mimari tasarım ve iyi kod hakkında daha fazla farkındasın değil mi test dalmak değil. Ve burada OOP faydaları gerçekten parlamaya başlıyor. Muhakemesi kanunu iyi test edebilirsiniz, ama birbirine bağlı parçaları ile büyük bir proje için test iyi bir tasarım uygulayan bir yolu vardır. Bazı usul insanlar için troll yem olabilir ama oh iyi biliyorum.

Daha fazla test, daha fazla kendiniz kod yazmak ve kendinize, "bu test etmek mümkün Olacak mı?" diye soran bulabilirsiniz Ve eğer, muhtemelen yapının o zaman ve orada değiştireceksin.

Ancak, kod test edilebilir olması için temel olması gerekmez. Stubbing and mocking tamamen kontrolden çıktı, dış işlemleri test etmek için izin verir. Test veritabanı işlemleri ve hemen hemen başka bir şey için fixtures oluşturabilirsiniz.

Daha fazla test, daha fazla eğer zor bir zaman bir şey test yaşıyorum eğer temel bir tasarım sorunu var, çünkü büyük olasılıkla olduğunu fark ettim. Ben bunu düzeltmek için ise genellikle test sonuçlarımın hepsi yeşil bar olur.

Son olarak, burada gerçekten beni test-dostu bir şekilde düşünmeye başlamak için yardımcı linkler vardır. Birincisi a tongue-in-cheek list of what NOT to do if you want to write testable code. Eğer tüm siteye göz atarsanız aslında 0 kod kapsama için yolda size yardımcı olacak yararlı şeyler bir sürü bulabilirsiniz. Başka bir yararlı Madde discussion of dependency injection Bu.

İyi şanslar!

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Joanna Okrajni

    Joanna Okraj

    4 EYLÜL 2010
  • kindlechatmail

    kindlechatma

    25 AĞUSTOS 2010
  • krotoflik

    krotoflik

    26 ŞUBAT 2011