Ááá

Další web používající WordPress

Čer

21

Jak vynutit generování LINQ to SQL tříd 0

Narazil jsem na jeden starý bug v LINQ to SQL designeru ve Visual Web Developeru, díky kterému mi po změně DBML souboru zmizí .designer.cs soubor a nový se nevygeneruje.

Bohužel nevím jak chybu reprodukovat, protože nikdy dřív jsem se změnami v DBML žádný problém neměl. Asi se to vyskytuje jenom někdy.

Naštěstí jsem našel funkční workaround: Když DBML soubor v Solution Exploreru přejmenuju, tak se příslušný .designer.cs přegeneruje. Přejmenuju zpátky a je to.

Kvě

31

Import dat z MySQL do SQL Serveru 0

Dneska trochu praktičtěji. Jak na localhostu přenést data z MySQL do SQL Server Express.

Je to vpodstatě jednoduché, nejdřív nainstalujete MySQL Connector ODBC, pak si vytvoříte DSN („Zdroje dat (ODBC)“, součást Windows) a nakonec se proklikáte wizardem „Import and Export Data“, který je součástí SQL Serveru:

Jediné úskalí je v tom, že v konfiguraci MySQL (soubor my.ini) musíte nejdřív nastavit sql-mode="ANSI". Jinak se při pokusu o import dočkáte syntax error.

Stručně v obrázcích:

1.

mysql-odbc-configuration1.png

2.

zdroje-dat-odbc.png

3.

myini-sqlmode-ansi.png

4.

import-choose-data-source.png

Naimportuje to i strukturu, ovšem bez klíčů. Takže jako další krok je nutné nově vytvořenou databázi si projít a doupravit. Na to lze doporučit třeba SQL Server Management Studio Express, které je zdarma a nainstalujete ho nejsnáz přes Web Platform Installer.

Kvě

24

Co mám proti MVC 7

Posledních pár týdnů jsem na programování kašlal, trochu jsem přehodnocoval priority a nakonec jsem se rozhodl, že přejdu na ASP.NET MVC. Nejdřív ale popíšu, co se mi na něm (a taky na Nette, Rails a dalších) tolik nelíbí.

Přes půl století panuje snaha přiblížit „počítačové jazyky“ jazykům lidským. Zlatým grálem programování je, aby i úplný debil mohl vytvořit program prostě tím, že ho vlastními slovy popíše. Přiblížení k tomuto cíli bylo motivací pro vznik všemožných abstrakcí, které umožňují popsat počítači určitý problém zas o něco přirozeněji než dřív.

Jak byste laicky popsali webovou aplikaci (představte si, že jste BFU)? Jako soustavu controllerů, na kterých je možné volat akce, které vrací view? To asi ne. Já bych mluvil o soustavě stránek, na kterých jsou odkazy a formuláře, jejichž odkliknutím lze vykonat nějakou akci a případně přejít na jinou stránku. Něco v tom smyslu.

Připadá mi, že Rails a jeho následníci zavádí nepřirozenou abstrakci. Programátor si to musí v hlavě tlumočit, například: „Chci přidat stránku → chci přidat akci a view“. Při komunikaci s uživateli budete mluvit opět o stránkách (aby vám rozuměli) a v duchu si to překládat na nepřirozené „akce“…

Podle mě přístup MVC/MVP, jak se začal prosazovat v posledních pár letech, je šlápnutím vedle. Ale uvědomil jsem si, že já nechci psát žádný framework, takže musím nutně vybírat z toho, co tu je. Proto jsem opustil koncept svého vlastního frameworku a psaní frameworků rád přenechávám jiným.

Přes koncepční výhrady, ASP.NET MVC je momentálně prostě nejlepší…

Bře

28

LINQ to SQL a změny v databázi 1

LINQ to SQL je skvělá věc, ale pár věcí by ještě bylo potřeba dotáhnout. Pokud provedete změny v databázové struktuře, Visual Studio nenabízí žádnou pomůcku, která by je vám pomohla reflektovat ve vašich LINQ to SQL třídách.

V počátečních fázích vývoje může stačit v takovém případě prostě patřičné entity z DBML souboru odstranit a tabulky tam natahat znovu, ale jakmile si začnete mapování přizpůsobovat (přejmenovávat entity, přejmenovávat sloupce, navěšovat události apod.), tak tahle možnost už nepřichází v úvahu.

Existuje komerční add-in Huagati DBML/EDMX Tools (od $50), který kromě pár dalších věcí umí i přenášet změny z databáze do LINQ to SQL tříd. Jenže Express edice Visual Studia nemají podporu add-inů, takže nic pro mě.

Jediná možnost, na kterou jsem přišel (tady), spočívá v tom, že si do designéru přetáhnu novou kopii změněné tabulky, změny do té staré přenesu copy-pastováním a novou smažu:

dbml-copy.png

Bohužel takhle snadno nelze kopírovat vazby mezi entitama, na to už musíte otevřít zdrojový kód DBML souboru. Lišta Design / Split / Source, známá z Web Form editoru, tady bohužel chybí, ale když na soubor kliknete pravým myšítkem v Solution Exploreru, máte tam i volbu Open With…, která vám umožní soubor otevřít v XML editoru (DBML není nic než XML):

dbml-open-with.png

Moc nadšený z toho nejsem. Nezbývá než doufat, že s tím něco udělají ve VS 2010…

Bře

21

Další podivnost ve VWD 1

Visual Web Developer si na mě nachystal další překvápko, z ničeho nic mi začal hlásit zvláštní chybu asi tak na stovce míst v kódu:

Error 59 The call is ambiguous between the following methods or properties: 'PokerZpravy.ControlExtension_GetPublicParameters.GetPublicParameters(System.Web.UI.Control)' and 'PokerZpravy.ControlExtension_GetPublicParameters.GetPublicParameters(System.Web.UI.Control)' C:\Users\Václav\Documents\Visual Studio 2008\Projects\PokerZpravy\Tests\GetPublicParametersTest.cs 40 25 PokerZpravy

Přeložené do češtiny to znamená asi to, že kompilátor neví, jestli chcete volat A nebo A.

Celý probém byl nakonec v tom, že se mi nějakým záhadným způsobem do referencí projektu dostalo assembly projektu samotného. Nejspíš se to povedlo při přidání custom controlů do toolbaru. Stačilo odstranit referenci a zase všechno funguje. :-)

Bře

21

Error creating control 0

Tak na tomhle jsem se zasekl na pěkných pár dnů:

error-creating-control.png

Je to nějaká chyba v .NET Frameworku 3.5 SP1, která způsobuje, že po přeložení a refreshování custom web controlu se místo něj v editoru zobrazí podobná hláška. Na různých stránkách Microsoftu je tento problém popsaný: Něco se člověk dočte na code.msdn.micro­soft.com, něco na support.micro­soft.com a něco na connect.micro­soft.com, hotové puzzle…

Nakonec jsem postupně nainstaloval tyto hotfixy:

  • KB961847 – „Error creating control- [text] property“ ASP.NET server cntls in VS. Podle názvu a popisu jsem v něj vkládal největší naděje, ale problém přetrvával i potom.
  • KB961864 --_pendingCallbac­ks[…].async' is null on ASP.NET 2.0 AJAX site. Vůbec netuším, co s tím má společného, ale tohle KB číslo bylo zmíněné jako řešení na relevantní stránce podpory. Efekt se opět nedostavil.
  • KB967535 – IIS 7.0 Request.Tran­smitFile / Request.WriteFile not working expected. Další oprava řešící něco úplně jiného, tento byl prozměnu poraděn v Microsofťáckém bugtrackeru jako workaround. Nicméně po nainstalování této aktualizace konečně problém zmizel a já můžu pokračovat v započaté práci.

Nevím, jestli první dva hotfixy něčemu pomohli, spíš bych řekl, že ne. Ale kdo ví…

Úno

8

Jak simulovat paralelní přístupy? 10

Myslel jsem, že už to mám, ale byla to slepá cesta.

Můj postup byl takový, že jsem si vytvořil testy v Selenium IDE, nastavil Selenium Core a pak vytvořil dávku, která ty testy dokázala spustit v předem určeném počtu Firefoxů, pokaždé s jiným prázdným profilem:

@ECHO OFF
SETLOCAL

REM Nastavení.
SET count=20
SET firefox_path="c:\Program Files\Mozilla Firefox\firefox.exe"
SET testUrl="http://localhost:12345/Selenium/core/TestRunner.html?test=../tests/TestSuite.html&resultsUrl=../postResults&auto=true"
SET profilePrefix=%TEMP%\TestProfile


REM Spuštění %count% instancí Firefoxu.
FOR /L %%i IN (1,1,%count%) DO MKDIR "%profilePrefix%%%i"
FOR /L %%i IN (1,1,%count%) DO ECHO user_pref("browser.shell.checkDefaultBrowser", false); user_pref("browser.startup.homepage_override.mstone", "rv:1.9.0.3"); > "%profilePrefix%%%i\prefs.js"
FOR /L %%i IN (1,1,%count%) DO %firefox_path% -no-remote -profile "%profilePrefix%%%i" %testUrl%


ECHO Ted chvilku pockejte na dobehnuti vsech testu.
PAUSE


REM Úklid.
TASKKILL /IM firefox.exe /T /F
FOR /L %%i IN (1,1,%count%) DO RMDIR /S /Q "%profilePrefix%%%i"
ENDLOCAL

Takhle s dvaceti okny to ještě ujde, obsazení paměti mi vyšplhá jenom na nějakých 85%:

clipboard01.png

Jenže 20 je málo. To už se na podobné testování můžu rovnou vykašlat, jako všichni ostatní. Zkusil jsem nastavit 50 (i to je pořád málo), během chvilky se počítač stal totálně nepoužitelným a trvalo půl hodiny, než se mi podařilo přerušit tu dávku a taskkillnout ty firefox.exe procesy…

Takže tudy cesta nevede. :-(

Úno

4

Thread-safety a webové aplikace 0

Jeden z nejdůležitějších aspektů, jeden z nejméně testovaných.

Prolog

Představte si modelovou situaci:

  • Zpřístupníte světu webovou aplikaci, kterou jste pečlivě ze všech stran otestovali a jste si jistí, že funguje správně.
  • Ze začátku o ni není velký zájem, ale těch pár lidí, co ji občas použije, si ji nemůže vynachválit a tak časem začne uživatelů přibývat. Word of mouth.
  • Pak se stane něco divného. Nějaká data se ztratí, nějaký uživatel dostane cizí data, něco se uloží dvakrát apod.
  • Zaboha nemáte tušení, čím to bylo. Nakonec to svedete na skvrny na slunci a pustíte to z hlavy.
  • S rostoucí popularitou podobných situací začne přibývat.
  • Jak podobých incidentů začne přibývat, začne se šířit pověst o nespolehlivé aplikaci. Popularita a důvěra klesá. Word of mouth.

Takhle můžete dopadnout, když nevěnujete dostatečnou pozornost tomu, co se všechno může stát, pokud k vaší aplikaci přistupuje více lidí zároveň.

Na co dávat pozor

Pozor je potřeba dávat vždy, když přistupujete k nějakým sdíleným zdrojům. Sdílené zdroje = cokoli mimo kontext aktuálního HTTP požadavku. Příkladem sdílených zdrojů jsou hlavně soubory a databáze, ale zdaleka nejen.

V některých prostředích, včetně ASP.NET, také statické členy tříd. Přestože pro každý požadavek se vytváří nová instance stránky, nový HttpContext a spousta dalších věcí, samotné třídy jsou v celé aplikaci sdílené (rozdíl od PHP). Lze snadno ověřit:

<%@ Page Language="C#" Inherits="System.Web.UI.Page" %>
<script runat="server">
    static string Blah = "Default value.";
</script>

<html>
<body>
    <p>
        <%= Blah %>
        <% Blah = "Changed value."; %>
    </p>
</body>
</html>

Při prvním spuštění vypíše „Default value“, při každém dalším obnovení stránky „Changed value“, až do restartu aplikace. Ovšem lze kód upravit tak, aby ten člen byl „statický“ jen v rámci aktuálního požadavku:

static string Blah
{
    get { return HttpContext.Current.Items["Blah"] as string; }
    set { HttpContext.Current.Items["Blah"] = value; }
}

HttpContext.Current je sice také statická property, ale používá různé instance HttpContext podle toho, z kterého ji voláme threadu.

Přístupy ke sdíleným zdrojům je nutné nějak synchronizovat. Aby například během procesu zápisu do souboru (od otevření až do zavření), žádný jiný thread nemohl ten soubor číst. Ale to teď nechám být, teď mi jde jenom o odhalení těch přístupů.

Dávat pozor nestačí

Jenže dávat pozor nestačí.

Často si nemusíte uvědomit, že zdroj, ke kterému přistupujete, je sdílený. Někdy to ani nemusí být moc zřejmé (třeba nějaké knihovny třetích stran můžou používat statické členy vnitřně). Nebo si nemusíte uvědomit, že některá operace není atomická.

Před třemi lety bych vůbec nepřemýšlel, jestli PHP funkce file_put_contents() je nebo není atomická. Kdyby mě to bylo napadlo, tak bych býval během chvilky splácl jednoduchý test, ale mě to ani nenapadlo… Udělal jsem za tu dobu dostatečný pokrok, abych se mohl spolehnout jen na svůj úsudek? Na to bych nespoléhal.

Epilog

Logicky tedy vyvstává potřeba nějak testovat chování aplikace při více uživatelích naráz. Zkoušel jsem najít nějaké nástroje a postupy, které by v tomhle pomáhali, ale asi jsem špatně hledal.

Představuju si to asi tak, že nadefinuju uživatelské kroky, které pak nechám provést třeba 50 robotů zároveň.

Nakonec jsem si vytvořil takovou jednoduchou utilitku sám. Používá Příkazový řádek, Selenium a spoustu Firefoxů… Až udělám nějaké screenshoty, sepíšu o tom článek a hodím to sem.

Ale už teď mě zajímá: Testujete nějak chování aplikace pod palbou uživatelských akcí, ještě před jejím vypuštěním?

Led

3

Rok 2008 17

Rozhodl jsem se shrnout svůj vývoj na poli programování. Vzhledem k tomu, že si na to najdu čas sotva pár hodin týdně a někdy ani to ne, tak je toho docela dost.

Začátkem roku jsem si začal psát vlastní PHP framework, vycházející ze vzoru Page Controller.

Pak jsem si napsal i vlastní testovací nástroj. Na Simpletestu i PHPUnit mi z několika důvodů vadilo, že se testy spouští postupně v jednom vlákně. Tak jsem si ubastlil takový ošklivý skript, který ajaxem posílal kupu požadavků na provedení jednotlivých testů.

Bylo to o něco rychlejší, testy byly lépe izolované a navíc jsem tím měl i trochu ošetřenou thread safety: Kdyby nějaký kód nebyl thread safe, tak by se to pravděpodobně projevilo ještě při testech.

Na jaře jsem se zasekl, protože se mi začaly hromadit duplicity mezi Modelem a View a nevěděl jsem, co s tím. Pořád nevím…

Do toho jsem začátkem srpna přešel od PHP k Javě. Tím jsem veškeré dosavadní výtvory zahodil (tak moc toho zas nebylo :-) ).

Koncem srpna jsem přešel od Javy k .NET, protože na malé webové projekty se Java nehodí.

Od té doby se tak trochu plácám. ASP.NET se dá do vysoké míry přizpůsobit, ale ne vždy je snadné přijít na to, jak.

Hodně času jsem třeba strávil tím, že jsem chtěl testovat instance stránek. Představoval jsem si testy, které by probíhaly přibližně takto:

  • Vytvořit instanci stránky "~/default.aspx".
  • Provést request.
  • Ověřit, jestli vlastnosti určitých controlů nabývají správných hodnot.

To se mi do jisté míry podařilo, ale byl to porod a pořád ještě nevím, jak nasimulovat třeba POST request. Navíc po proběhnutí testu občas vylétá jakási výjimka. (Viz ASP.NET fórum.)

A takhle je to se vším. Jakmile se rozhodnu dělat něco jenom trošku jinak než je obvyklé, tak narazím…

Lis

8

NUnit versus ostatní 1

NUnit je v současnosti nejpíš nejrozšířenější .NET framework pro testování jednotek. Nebo přinejmenším nejvyhledávanější, v Google Trends ostatní bezpečně válcuje.

Čím dál častěji různě narážím na zmínky buďto o xUnit.org, nebo o testech zabudovaných v týmové edici Visual Studia (MSTest). Na stránkách k xUnit.org jsem našel přehlednou srovnávací tabulku, kterou lze shrnout asi takhle:

  • NUnit, MbUnit, MSTest: Třikrát to samé, pouze drobné rozdíly v zápisu ([Test] vs. [TestMethod] apod.).
  • xUnit.net: Některé věci dělá jinak, než je obvyklé. Především:
    • Pro každý test se vytváří nová instance testovací třídy. Z toho vyplývá:
      • Testy jsou lépe izolované.
      • Žádné SetUp/TearDown metody. Testy lze inicializovat v konstruktoru a uklidit případně v IDisposable.Dispose.
    • Testovací metodě se říká „fact“.
    • Testovací třída nemusí být nijak označená. Stačí, že jsou označené testovací metody.

xUnit.net je dost zajímavý kousek softwaru. Co mu podle mě hodně schází, je Assert.That. Tedy možnost například místo staromódního zápisu:

Assert.AreEqual(expected, actual);

Používat jiný zápis:

Assert.That(actual, Is.EqualTo(expected));

Tento zápis se víc blíží přirozenému jazyku (Věta „assert that actual is equal to expected“ docela dává smysl, ne?) a je docela návykový. Podle mě je otázkou času, kdy ho adoptuje i xUnit.net.

Související: Raroušův článek o xUnit.net

« Previous Entries
Další možnosti...

Blogroll

  • Blog vývojářů
  • Česká verze
  • Dokumentace
  • Fórum podpory
  • Motivy vzhledu
  • Pluginy
  • Vaše nápady
  • WordPress Planet
  • Pages

    • Diakritika v doméně? WTF?
    • O těchto stránkách

Your List

  • Your list items
  • Your list items
  • Your list items
  • Your list items
  • Your list items

© Ááá * WordPress * LoseMyMind * Feed feed