Archiwa tagu: csharp

Prosta walidacja maila w C#

Żeby sprawdzić poprawność adresu email, wcale nie trzeba męczyć się ze skomplikowanymi wyrażeniami regularnymi. W C# walidacja maila jest prosta – z pomocą przychodzi klasa MailAddress. Oczywiście jest to rozwiązanie wysokopoziomowe i wolne (rzuca wyjątki). Zapewnia jednak czytelność kodu.

Przykład (zaczerpnięty ze StackOverflow):

bool IsValid(string emailaddress)
{
  try
  {
    MailAddress m = new MailAddress(emailaddress);
    Console.WriteLine("TRUE" + "\t" + emailaddress);
    return true;
  }
  catch
  {
    Console.WriteLine("FALSE" + "\t" + emailaddress);
    return false;
  }
}

Testy – walidacja maila:

IsValid("ok@ok.pl");
IsValid("dolores.ryba@poczta-n.pl");
IsValid("dolores.ryba@poczta.odlotowa.pl");
IsValid("dolores.ryba@a.b.c.d.pl");
IsValid("psikus@dot.dot.dot..pl");
IsValid("@");
IsValid("");
IsValid(null);
IsValid("bad@");
IsValid("@wolf");
IsValid("@poczta.pl");
IsValid("cokolwiek");

Czytaj dalej

How to run tests in Visual Studio?

How to run tests (unit tests, Selenium or any other in Microsoft Visual Studio? This is quite simple.

My instruction is for Visual Studio Professional 2015.

  1. First – choose test runner (nUnit, MSTest, xUnit or other). I choosed nUnit, because of its popularity.
  2. Install a test runner. I use NuGet to manage dependencies in my projects. To install nUnit, click (right) on project and click „Manage NuGet Packages”, search „nUnit” and install it. A current version number is 3.4.1.
  3. Prepare a simple test. Remember about:
    • making class containing tests public (public class TestClass{})
    • making test methods public (public void TestMethod(){})
    • marking test methodss with [Test] attribute.
  4. Prepared test should be visible in Test Explorer (open this window from menu: Test -> Windows -> Test Explorer). If Test Explorer window is empty and after building project Visual Studio doesn’t display any tests, you need to install nUnit Test Adapter (version 3.x is compatible with nUnit 3.x). To install nUnit Test Adapter, choose „Extensions and Updates” from „Tools” menu, search for „nUnit Test Adapter” and install it. After rebooting Visual Studio and rebuilding project, tests should be displayed in Test Explorer Window.

C# – jak używać nullable i parsować je do typów prostych

Typy nullable to bardzo sympatyczne zwierzęta. Poza klasycznymi wartościami umożliwiają przypisanie zmiennym prostym niedozwolonej dla nich wartości null – zupełnie jak dla typów referencyjnych.

Do czego można tego użyć? Pierwsza moja styczność z nullable miała miejsce w zamierzchłych czasach studenckich praktyk. Używałam wtedy nullable do przechowywania wartości z pól w formatce (we współpracy z TryParse). Niedawno natomiast zastosowałam nullable int w liście argumentów do metody – użytkownik ma możliwość pominięcia niektórych wartości (wstawienie -1 czy 0 nie rozwiązywało sprawy, gdyż były to również wartości znaczące).

Jak zachowują się takie nullable w prawdziwym życiu? Jak najprościej skonwertować je do typu prostego?

Proste demo – dzięki zastosowaniu default nie ma konieczności używania Parse ani TryParse:

var nullables = new List<int?> {null, -1, 0, 1};
foreach (var nullable in nullables)
{
  var intable = nullable ?? default(int);//magiczna linia
  Console.WriteLine("{0} \t-> {1}", nullable, intable);
}

Oraz wynik:
null -> 0
-1 -> -1
0  -> 0
1  -> 1

C# – Mierzenie czasu wykonania metod

Mierzenie czasu wykonania metod w C#. Bardzo proste i sprawnie działające. Ostatnimi czasy używam głównie do porównywania wydajności implementacji różnych podejść, które przyjdą mi do głowy.


var watch = Stopwatch.StartNew();

//tu metody, których czas mierzysz

watch.Stop();

var elapsedMs = watch.ElapsedMilliseconds;

var czekaj = true;//tu ustaw sobie pułapkę* i odczytaj wartość ze zmiennej elapsedMs

* pułapka – niezmiennie cieszy mnie to polskie tłumaczenie breakpointa 😉

Sprawdzanie czy checkbox jest zaznaczony w Selenium (C#)

Każdy z obiektów znalezionych przez Selenium jest standardowym obiektem typu WebElement. Udostępnia on następujące metody (których wartość zwracana jest typu bool):

  • displayed – element jest widoczny.
  • enabled – element jest aktywny – można go kliknąć, wpisać mu wartość itd. W praktyce każdy element dostępny na stronie ma stan enabled, gdyż jest to stan domyślny. „Wyłączyć” można go jedynie poprzez celowe dodanie do HTML atrybutu disabled. Element z takim atrybutem będzie „wyszarzony”.
  • checked – element jest zaznaczony. Dotyczy pól typu input – zarówno typu radio jak i checkbox.

Kawałek kodu HTML-owego, do którego zastosuję Selenium:


<html>
<body>
<form>
<input type="checkbox" />
</form>
</body>
</html>

Oraz fragment kodu C# z wykorzystaniem Selenium:


[Test]
public void CheckboxIsChecked()
{
  driver.url="file:///C:/DOCUMENTS/test.html";
  var el = driver.FindElement(By.TagName("input"));
  var before = el.Selected;//false
  el.Click();
  var after = el.Selected;//true
}

C#: czym różni się First od FirstOrDefault

Stosowanie wyrażeń lambda i LINQ może w znaczący sposób skrócić kod.

Jednym z częściej używanych funkcji jest funkcja pozwalająca wybrać pierwszy element z kolekcji (może posortowanej wcześniej funkcją Sort(), może potraktowanej wyrażeniem Where()). Do wyboru mamy użycie funkcji First() lub FirstOrDefault(). Czym się różnią?

First() zwraca pierwszy argument z listy. Jeśli lista jest pusta, rzucany jest wyjątek.

FirstOrDefault() zwraca pierwszy argument z listy. Jeśli lista jest pusta, zwracany jest element domyślny.

A jaki to jest element domyślny?

Dla typów prymitywnych typu int – wartość domyślna to 0. Dla typów obiektowych – null.

Całość można łatwo przetestować. Zrobiłam sobie np. taki obiekcik, żeby za jednym zamachem sprawdzić zachowanie się na obiekcie, jak i na incie:

class IntWrapper
{
  public readonly int IntValue;
  public IntWrapper(int intValue)
  {
    IntValue = intValue;
  }
}

I kod testujący:

var list = new List<IntWrapper> {new IntWrapper(5), new IntWrapper(10), new IntWrapper(15)};
/*var result1 = (from r in list
              where r.IntValue.Equals(200)
              select r).First(); */ //exception!

var result2 = (from r in list
              where r.IntValue.Equals(200)
              select r).FirstOrDefault();//default value: null

var list2 = new List<int> { 5, 10, 15 };
/*var result3 = (from r in list2
              where r.Equals(200)
              select r).First();*/ //exception!

var result4 = (from r in list2
              where r.Equals(200)
              select r).FirstOrDefault();//default value: 0

Selenium: Exception „Compound class names are not supported”

Today something about one of exceptions that can occure in Selenium PageFactory.

IllegalLocatorException was unhadled by user code.
An exception of type „OpenQA.Selenium.IllegalLocatorException” occured in WebDriver.dll but was not handled in user code.
Additional information: Compound class names are not supported. Consider searching for one class name and filtering the results.

In my case, this exception was thrown in line:

PageFactory.InitElements(webDriver, pageElement);

This is probably a bug in Selenium. Solution is easy: just do not use:

[FindsBy(How=How.ClassName, Using="name_of_class"]

Instead of ClassName, try to use Css Selectors:

[FindsBy(How=How.CssSelector, Using=".name_of_class"]

Remember about a dot!

Asert w NUnit

Jednym z bardziej elementarnych składników testów są asercje, umożliwiające sprawdzenie, czy spełnione są warunki testu.

W NUnicie dostępnych jest wiele różnych asercji. Najprostsza to:

Assert.AreEqual

To jednak nie wszystko. NUnit oferuje cały wachlarz asercji – warto spojrzeć w dokumentację [equalConstraint][assertions].

Bardzo fajną opcją jest na przykład sprawdzenie, czy kolekcja jest posortowana:

var notSorted = new List<decimal>();

notSorted.Add(12.3);

notSorted.Add(5.5);

notSorted.Add(100);

Assert.That(notSorted, Is.Ordered);//Fail

Poza klasycznymi asercjami NUnit oferuje też np. StringAsert, CollectionAsert itd.

Przekazywanie parametrów do funkcji – Java kontra C#

Parametry przekazywane do funkcji w Javie są przez wartość, co oznacza że wewnątrz funkcji operujemy na kopii obiektu. I kropka. W przypadku typów prostych faktycznie nie ma problemu:

int mainInt = 60;
System.out.println("mainInt before changes: " + mainInt);
m.changePrimitive(mainInt);
System.out.println("mainInt after changes: " + mainInt);
public void changePrimitive(int localInt){
localInt = 3;
System.out.println("localInt in function: " + localInt);
}

mainInt before changes: 60
localInt in function: 3
mainInt after changes: 60

W przypadku typów obiektowych (referencyjnych) również kopiowany jest obiekt, lecz w praktyce wygląda to nieco inaczej niż w przypadku typów prostych. Czytaj dalej