Re[13]: Ошибок не делает тот, кто ничего не делает
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 31.03.07 05:54
Оценка: -1
Здравствуйте, minorlogic, Вы писали:

M>Так значит и не надо этот модуль делать надежным. Кому надо , тот заплптит и за юнит тесты


То есть юнит-тесты нужно применять, когда кто то за это заплатит. Очень здравая мысль.
... << RSDN@Home 1.2.0 alpha rev. 675 on Windows Vista 6.0.6000.0>>
AVK Blog
Re[3]: Можно парочку дерзких вопросов?
От: MatFiz Россия  
Дата: 31.03.07 19:09
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Хм. А вот что делать, если мне нужно реализовать процедуру умножения транспонированных матриц (очень просто, неправда ли?).

FDS>Варианты реализации:

FDS>1. Для того, что бы перемножить некоторым образом транспонированные матрицы я их транспонирую отдельной функцией и затем передаю в обычную процедуру умножения матриц

FDS>Минус: понижение производительности. Ведь я мог бы перемножить матрицы без физического транспонирования

Матрицу физически транспонировать и не надо.
Сделай у матрицы флаг транспонированности, а внутри свойства доступа к элементам матрицы меняй индексы местами, если флаг транспонированности установлен.
Или, если боишься if-а при доступе к элементам матрицы, сделай класс "транспонированная матрица", унаследованный от матрицы, имеющий внутри ссылку на исходную матрицу и оверрайдни свойство доступа к элементам.
How are YOU doin'?
Re[8]: Можно парочку дерзких вопросов?
От: Mirrorer  
Дата: 02.04.07 06:03
Оценка:
Здравствуйте, IT, Вы писали:

IT>На бумажке уже даже не помню когда писал. Писать начинаю в коде сразу, даже ещё не понимая что получится в результате. [cut] При таком подходе опысываемые тобой ошибки исключены.


А как можно при таком подходе оценить время необходимое на реализацию ?
"Если Вы отличаетесь от меня, то это ничуть мне не вредит — Вы делаете меня богаче". Экзюпери
Re[4]: Как Вы боретесь с ошибками?
От: Mirrorer  
Дата: 02.04.07 06:42
Оценка:
Здравствуйте, IT, Вы писали:

IT> Только, к сожалению, по моим наблюдениям между умением говорить такие банальности и умением их применять лежит огромная пропасть, мостиком через которую как раз и являются практические приёмы и навыки.


В самую точку.
"Если Вы отличаетесь от меня, то это ничуть мне не вредит — Вы делаете меня богаче". Экзюпери
Re[9]: Можно парочку дерзких вопросов?
От: IT Россия linq2db.com
Дата: 02.04.07 12:14
Оценка:
Здравствуйте, Mirrorer, Вы писали:

IT>>На бумажке уже даже не помню когда писал. Писать начинаю в коде сразу, даже ещё не понимая что получится в результате. [cut] При таком подходе опысываемые тобой ошибки исключены.


M>А как можно при таком подходе оценить время необходимое на реализацию ?


Очень просто. Это время равно от нуля, до времени необходимого на подчистку кода.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Ошибок не делает тот, кто ничего не делает
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 00:44
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>Кстати, какой процент известных ошибок помогла поймать статическая типизация?


100% ошибок типов.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: Ошибок не делает тот, кто ничего не делает
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 00:44
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

ANS>То для чего можно написать юнит-тест То есть кусок кода, который можно выполнить не инициализируя всего приложения. Где-то так.


Вообще-то технология давно отлажана. Клепаешь фэйк-объекты (МОК-объекты) и оборачиваешь ими все что не лезет в концепцию юнит-тестов. Далее загружаешь нужное состояние и вперед.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Ошибок не делает тот, кто ничего не делает
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 00:44
Оценка:
Здравствуйте, Andrei N.Sobchuck, Вы писали:

AVK>>Янус спроектирован таким образом. Только проблема там в другом месте.


ANS>О да. Просвети нас, чем же именно уникален Янус?


Это скорее к тебе вопрос.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Как Вы боретесь с ошибками?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 01:23
Оценка: :)))
Здравствуйте, IT, Вы писали:

IT>1. Настоящий индеец прежде всего заходит в меню Debug и в диалоге Exceptions включает галку Thrown на CLR Exceptions для managed языков. Это позволяет сэкономить не просто хучу, а туеву хучу времени при поиске ошибок. Отсюда следствие — настоящие индейцы не используют логику на исключениях, иначе весь кайф пропадает.


Жаль мы с тобой все же не всегда настоящие индейцы. Потому как после того как ты в Интеграции сам знаешь чего реализовал комбы со списками типов и методов в редактироуемом файле, то сразу стала проявляться суть настоящего индусяцкого кода лежащего в:
...\VsSDK\2007.02\VisualStudioIntegration\Common\Source\CSharp\LanguageService\CodeWindowManager.cs
// Omitting any of the following operator overloads
// violates FxCop rule: IComparableImplementationsOverrideOperators.
/// <include file='doc\CodeWindowManager.uex' path='docs/doc[@for="DropDownMember.Operator=="]/*' />
public static bool operator ==(DropDownMember m1, DropDownMember m2) {
        return m1.Equals(m2);
}

приводящего к ловине:
System.NullReferenceException occurred
  Message="Object reference not set to an instance of an object."
  Source="Microsoft.VisualStudio.Package.LanguageService"
  StackTrace:
       at Microsoft.VisualStudio.Package.DropDownMember.op_Equality(DropDownMember m1, DropDownMember m2)


Вот так один индус может испортить жизнь двум индейцам.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Можно парочку дерзких вопросов?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 01:23
Оценка:
Здравствуйте, IT, Вы писали:

FDS>>Формой с методами обработки информации.


IT>Т.е. написал для отладки отдельный гуй?


А почему нет если задача требует? Вот представь, ты должен отдать список иконок другому приложнию (студии, например). Самый прсотой способ убедиться, что с картинками все ОК — склепать примитивную форму с ЛистВью в который выведены иконки.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Можно парочку дерзких вопросов?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 01:23
Оценка:
Здравствуйте, IT, Вы писали:

IT>>>Кстати, один из способов, позволяющих решить эту проблему, это локальные функции. К сожалению, в C# этого нет, и пока, как я понял не планируется.


M>>Ну можно это будет лямбдами сэмулировать. Хотя для 3х уровней вложенности это ужастик получится, да.


IT>На каждую такую функцию уморишься делегаты ообъявлять. Короче, лажа это. Без крайней необходимости никто этим пользоваться не будет.


Кстати, илюстрация к грусному. По причине завязанности алгоритма на некоторые классы Студии был вынужден писать класс-хелпер на C# 2.0. Но к лямбдам и т.п. как-то прям тянет. В итоге родилось вот такое чудо:
#region MatchBraces()

private AuthoringScope MatchBraces(ParseRequest request)
{
  if (!request.Sink.BraceMatching)
    return GetDefaultScope(request);

  // Steps: 
  // 1. Find token under text caret.
  // 2. Determine that it is a paired token.
  // 3. Determine paired token.
  // 4. Find paired token in the source file.
  // 5. Set info about paired tokens Sink and return it in AuthoringScope.

  #region Init vars

  ProjectInfo projectInfo = GetProjectInfo(request);

  if (projectInfo == null)
    return GetDefaultScope(request);

  NemerleSource source = projectInfo.GetSource(request.FileName);
  IVsTextColorState colorState = source.ColorState;
  Colorizer colorizer = source.GetColorizer();
  NemerleScanner scanner = (NemerleScanner)colorizer.Scanner;
  string lineText = source.GetLine(request.Line);
  scanner.SetSource(lineText, 0);

  #endregion

  // Steps: 1-3
  BracketFinder bracketFinder = new BracketFinder(source, request.Line + 1,
    request.Col + 1, scanner, colorState);

  // 4. Find paired token in the source file.
  ScanTokenInfo matchBraceInfo = bracketFinder.FindMatchBraceInfo();

  if (matchBraceInfo != null)
  {
    // 5. Set info about paired tokens Sink and return it in AuthoringScope.

    request.Sink.FoundMatchingBrace = true;

    // Fix a bug in MPF: Correct location of left token.
    // It need for correct navigation (to left side of token).
    Token mactTok = matchBraceInfo.Token;
    Location mactLoc = request.Reason == ParseReason.MatchBraces 
      && !BracketFinder.IsOpenToken(mactTok)
      ? mactTok.Location.FromEnd() : mactTok.Location;

    request.Sink.MatchPair( // Set tokens position info
      Convert(bracketFinder.StartBraceInfo.Token.Location),
      Convert(mactLoc), 0);

    return new NemerleAuthoringScope(
      projectInfo, request.Sink, request.FileName,
      new SourceTextManager(projectInfo.GetSource(request.FileName)));
  }

  return GetDefaultScope(request); // we don't fing paired token
}

#endregion

#region BracketFinder class

/// <summary>
/// Helper class which match paired token (brackets, brace, etc.)
/// </summary>
private class BracketFinder
{
  #region Fields
  
  public ScanTokenInfo StartBraceInfo;
  IVsTextColorState ColorState;
  NemerleSource Source;
  int StartLine;
  ScanLexer Lex;
  NemerleScanner Scanner;

  #endregion

  public BracketFinder(NemerleSource source, int startLine,
    int startCol, NemerleScanner scanner, IVsTextColorState colorState)
  {
    #region Init fields

    Scanner = scanner;
    Source = source;
    StartLine = startLine;
    Lex = scanner.GetLexer();
    Lex.SetFileName(source.GetFilePath());
    ColorState = colorState;
    
    #endregion

    #region 2. Determine that it is a paired token. 3. Determine paired token.
    
    // Get tokens of line under text carret into dynamic array.
    List<ScanTokenInfo> lineToks = GetLineTokens(startLine, true);
    // Find index of token which located under text carret.
    int index = FindIndex(lineToks,
      delegate(ScanTokenInfo x)
      { return x.Token.Location.Contains(startLine, startCol); });

    // If index is corret get corresponding token.
    ScanTokenInfo startBraceInfo = index < 0 ? null : lineToks[index];
    // Remember it, if token have paired token.
    if (IsPairedToken(startBraceInfo.Token))
      StartBraceInfo = startBraceInfo;
    else
    {
      // otherwise try get right-hand token...
      startBraceInfo = RightHand(lineToks, index);
      // Remember it, if token have paired token.
      if (IsPairedToken(startBraceInfo.Token))
        StartBraceInfo = startBraceInfo;
    } 

    #endregion
  }

  public ScanTokenInfo FindMatchBraceInfo()
  {
    if (StartBraceInfo == null)
      return null;

    // 4. Find paired token in the source file.

    Token tok = StartBraceInfo.Token;
    Predicate<Token> isStartBrace = GetMatchBracePredicate(tok);
    Predicate<Token> isEndBrace = GetMatchBracePredicate(GetPairedToken(tok));
    int nestedLevel = 1;

    foreach (ScanTokenInfo tokInfo in GetTokenIter())
    {
      if (isEndBrace(tokInfo.Token))
        nestedLevel--;
      else if (isStartBrace(tokInfo.Token))
        nestedLevel++;
      if (nestedLevel == 0)
        return tokInfo; // Match found!
    }

    return null; // Match not found.
  }

  #region GetTokenIter()

  /// <summary>
  /// Return iterator which allow iterate throw tokens of curent 
  /// source file. Iteration process start from token behind current 
  /// token and go forward or backward depending on type of start token.
  /// If start token is open token (for example, "(" or "{") iteration
  /// execute forward. If start token is close token (for example, ")" 
  /// or "]") iteration execute backward.
  /// </summary>
  private IEnumerable<ScanTokenInfo> GetTokenIter()
  {
    bool isScanForward = IsOpenToken(StartBraceInfo.Token);
    int startLine = StartLine;
    // 1. Для первой строки находим токен и начиная от него сканируем вперед или назад.
    List<ScanTokenInfo> tokInfs = new List<ScanTokenInfo>(
      GetLineTokens(startLine, isScanForward));

    int tokIndex = FindIndex(tokInfs, delegate(ScanTokenInfo ti)
      { return ti.Token.Location == StartBraceInfo.Token.Location; });
    if (tokIndex < 0)
      throw new Exception("tokInfs.IndexOf(startBraceInfo)");

    // Scan first line from "start bracket" index.
    for (int i = tokIndex + 1; i < tokInfs.Count; i++)
      yield return tokInfs[i];

    if (isScanForward) // Scan next lines.
      for (int i = startLine + 1, count = Source.GetLineCount(); i <= count; i++)
        foreach (ScanTokenInfo tokInf in GetLineTokens(i, true))
          yield return tokInf;
    else // Scan previous lines.
      for (int i = startLine - 1; i >= 0; i--)
        foreach (ScanTokenInfo tokInf in GetLineTokens(i, false))
          yield return tokInf;
  }

  #endregion

  #region GetLineTokens()

  /// <summary>
  /// Get tokens of specified line.
  /// </summary>
  /// <param name="line">Line number which tokens it is necessary retrieve</param>
  /// <param name="isForward">Direction of iteration (true is forward)</param>
  /// <returns>Token list</returns>
  List<ScanTokenInfo> GetLineTokens(int line, bool isForward)
  {
    ScanState scanState = GetLineState(line);
    string lineText = Source.GetLine(line - 1);
    Scanner.SetSource(lineText, 0);
    Lex.SetLine(line, lineText, 0, null, null);
    List<ScanTokenInfo> lst = new List<ScanTokenInfo>();

    foreach (ScanTokenInfo var in GetLineTokens(Lex, scanState))
      lst.Add(var.Clone());

    if (!isForward)
      lst.Reverse();

    return lst;
  }

  /// <summary>Return colorer lexer state for specified line.</summary>
  private ScanState GetLineState(int line)
  {
    int state;
    ErrorHandler.ThrowOnFailure(
      ColorState.GetColorStateAtStartOfLine(line, out state));
    return (ScanState)state;
  }

  /// <summary>
  /// Imlementation of GetLineTokens(). Don't use this method directly!
  /// </summary>
  IEnumerable<ScanTokenInfo> GetLineTokens(ScanLexer lex, ScanState scanState)
  {
    ScanTokenInfo info = lex.GetToken(scanState);
    scanState = info.State;
    while (!info.IsEndOfLine)
    {
      yield return info;
      info = lex.GetToken(scanState);
      scanState = info.State;
    }
  }

  #endregion

  #region Paired token identification functions

  public static bool IsOpenToken(Token token)
  {
    if (token is Token.BeginBrace) return true;
    if (token is Token.BeginQuote) return true;
    if (token is Token.BeginRound) return true;
    if (token is Token.BeginSquare) return true;

    if (token is Token.EndBrace) return false;
    if (token is Token.EndQuote) return false;
    if (token is Token.EndRound) return false;
    if (token is Token.EndSquare) return false;

    Token.Keyword kwd = token as Token.Keyword;

    if (kwd != null)
    {
      if (kwd.name == "if") return true;
      if (kwd.name == "else") return false;
    }

    throw new Exception("The token '" + token + "' not a brace!");
  }

  private static bool IsPairedToken(Token token)
  {
    if (token is Token.BeginBrace || token is Token.BeginQuote
      || token is Token.BeginRound || token is Token.BeginSquare
      || token is Token.EndBrace || token is Token.EndQuote
      || token is Token.EndRound || token is Token.EndSquare
    )
      return true;

    Token.Keyword kwd = token as Token.Keyword;

    if (kwd != null && (kwd.name == "if" || kwd.name == "else"))
      return true;

    return false;
  }

  /// <summary>
  /// Return predicate function which check it argument is same token .
  /// </summary>
  private static Predicate<Token> GetMatchBracePredicate(Token token)
  {
    if (token is Token.BeginBrace)
      return delegate(Token t) { return t is Token.BeginBrace; };
    if (token is Token.BeginQuote)
      return delegate(Token t) { return t is Token.BeginQuote; };
    if (token is Token.BeginRound)
      return delegate(Token t) { return t is Token.BeginRound; };
    if (token is Token.BeginSquare)
      return delegate(Token t) { return t is Token.BeginSquare; };

    if (token is Token.EndBrace)
      return delegate(Token t) { return t is Token.EndBrace; };
    if (token is Token.EndQuote)
      return delegate(Token t) { return t is Token.EndQuote; };
    if (token is Token.EndRound)
      return delegate(Token t) { return t is Token.EndRound; };
    if (token is Token.EndSquare)
      return delegate(Token t) { return t is Token.EndSquare; };

    Token.Keyword kwd = token as Token.Keyword;

    if (kwd != null)
    {
      if (kwd.name == "if")
        return delegate(Token t)
        {
          Token.Keyword kwd1 = t as Token.Keyword;

          if (kwd1 != null)
            return kwd1.name == "if";

          return false;
        };
      if (kwd.name == "else")
        return delegate(Token t)
        {
          Token.Keyword kwd1 = t as Token.Keyword;

          if (kwd1 != null)
            return kwd1.name == "else";

          return false;
        };
    }

    return null;
  }

  private static Token GetPairedToken(Token token)
  {
    if (token is Token.BeginBrace) return new Token.EndBrace(true);
    if (token is Token.BeginQuote) return new Token.EndQuote();
    if (token is Token.BeginRound) return new Token.EndRound();
    if (token is Token.BeginSquare) return new Token.EndSquare();

    if (token is Token.EndBrace) return new Token.BeginBrace(true);
    if (token is Token.EndQuote) return new Token.BeginQuote();
    if (token is Token.EndRound) return new Token.BeginRound();
    if (token is Token.EndSquare) return new Token.BeginSquare();

    Token.Keyword kwd = token as Token.Keyword;

    if (kwd != null)
    {
      if (kwd.name == "if")   return new Token.Keyword("else");
      if (kwd.name == "else") return new Token.Keyword("if");
    }

    return null;
  }

  #endregion

  #region Utils

  static T RightHand<T>(IList<T> lst, int index) where T : new()
  {
    int nextIndex = index + 1;
    if (nextIndex >= lst.Count)
      return new T();

    return lst[nextIndex];
  }

  private static List<T> Reverce<T>(IEnumerable<T> seq)
  {
    List<T> lst = new List<T>(seq);
    lst.Reverse();
    return lst;
  }

  static T Find<T>(IEnumerable<T> seq, Predicate<T> predicate) where T : class
  {
    foreach (T item in seq)
      if (predicate(item))
        return item;

    return null;
  }

  static int FindIndex<T>(IList<T> lst, Predicate<T> predicate) where T : class
  {
    for (int i = 0; i < lst.Count; i++)
      if (predicate(lst[i]))
        return i;

    return -1;
  }

  #endregion
}

#endregion
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Как Вы боретесь с ошибками?
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.04.07 01:37
Оценка:
Здравствуйте, IT, Вы писали:

_M>>но по крайней мере зверя ContextSwitchDeadLock я буду включать только через свой труп — он мне столько нервов попортил...


IT>Не включай. Я лично вообще такого исключения ни разу в жизни не видел.


Это похоже то из-за чего у нас отладка под студией навертывается .
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Как Вы боретесь с ошибками?
От: IT Россия linq2db.com
Дата: 04.04.07 01:52
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Вот так один индус может испортить жизнь двум индейцам.


Это точно. Приходится NullReferenceException отключать.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Ошибок не делает тот, кто ничего не делает
От: Andrei N.Sobchuck Украина www.smalltalk.ru
Дата: 04.04.07 06:52
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Вообще-то технология давно отлажана. Клепаешь фэйк-объекты (МОК-объекты) и оборачиваешь ими все что не лезет в концепцию юнит-тестов. Далее загружаешь нужное состояние и вперед.


Если нечто инициализируется где-то в недрах проги, то сделать мок может не быть возможности. В том то и вопрос, что нужно писать с учетом подобных операций.
Я ненавижу Hibernate
Автор: Andrei N.Sobchuck
Дата: 08.01.08
!
Re[5]: Как Вы боретесь с ошибками?
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 05.05.07 02:47
Оценка:
N>>В идеале, тесты должны полностью воссоздавать все окружение, в котором работает система. Например, если используется база данных, то хорошие тесты должны уметь создать ее "с нуля", прогнав необходимые скрипты, заполнить данными и "погонять" в разных режимах

_M>Такие тесты уже на юнит тесты мало похожи и если я правильно понял это называется тестированием интеграции. Сейчас пишу такой тест, получается что-то типа "виртуального пользователя", который совершает все возможные действия с программой, начиная "с чистого листа". Только результаты выполнения каждой команды сверять смысла нет, да и сложно это. Просто если во время выполнения какой-нибудь команды возникает ошибка (а в методах много проверок входных параметров, проверок промежуточных результатов), то всё это дело останавливается. Вроде нормально получается, я на правильном пути?


Почти. Результаты проверять надо. В этом как раз помогут мок-объекты.
Но для этого архитектура системы должна быть достаточно "слоистой" или хотя бы модульной.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[3]: Как Вы боретесь с ошибками?
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 05.05.07 02:52
Оценка:
IT>Это не всегда возможно. Точнее, это возможно для ограниченного круга задач.

На данном этапе развития технологий фактически возможно для большинства задач.
Просто конструировать надо сразу с расчётом на тестирование.
Или (в теории) на основе готовых тестов.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[3]: Ребят, я понимаю, что вам смешно, но проблема правда
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 05.05.07 02:58
Оценка:
FDS>Вместо того, чтобы смеяться, лучше бы подсказали, что я не так делаю... а то я уже скоро на Nemerle и Scheme начну писать лучше, чем на C# .

Улучшать архитектуру на высоком уровне.
Когда инкапсулируешь уже не данные и действия, а законченные решения.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[4]: Как Вы боретесь с ошибками?
От: IT Россия linq2db.com
Дата: 05.05.07 05:21
Оценка: +1
Здравствуйте, VGn, Вы писали:

IT>>Это не всегда возможно. Точнее, это возможно для ограниченного круга задач.


VGn>На данном этапе развития технологий фактически возможно для большинства задач.


UI в это большинство задач вписывается? 30 полей на форме с более менее зависимой логикой отображения и ты состаришься раньше, чем напишешь все возможные тесты. А когда напишешь, я добавлю ещё 10 полей. Только не в конец формы, а в случайном порядке с новой особенной логикой.

VGn>Просто конструировать надо сразу с расчётом на тестирование.


Конструировать надо не в расчёте на тестирование, а в расчёте на то, шоб оно работало как хочет клиент.

VGn>Или (в теории) на основе готовых тестов.


Ну да. Главное тесты, а без функциональности клиент как-нибудь переживёт.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Как Вы боретесь с ошибками?
От: VGn Россия http://vassilsanych.livejournal.com
Дата: 05.05.07 06:00
Оценка:
IT>UI в это большинство задач вписывается? 30 полей на форме с более менее зависимой логикой отображения и ты состаришься раньше, чем напишешь все возможные тесты. А когда напишешь, я добавлю ещё 10 полей. Только не в конец формы, а в случайном порядке с новой особенной логикой.

Утверждалась возможность, а не простота реализации, что тоже в конечном счёте вопрос инструментов.

VGn>>Просто конструировать надо сразу с расчётом на тестирование.

IT>Конструировать надо не в расчёте на тестирование, а в расчёте на то, шоб оно работало как хочет клиент.

Нет. Так говорят малограмотные ПМы.

Это требования формулировать необходимо на основе пожеланий клиента.
Тесты — на основе требований.
А код — удовлетворяющий этим тестам, а соответственно и всему остальному в обратном порядке.
Тогда мы всегда сможем трассировать пожелания-требования-тесты-код при изменении любой составляющей.
И в конечном счёте не будет обычного бардака с требованиями и реализацией.

VGn>>Или (в теории) на основе готовых тестов.

IT>Ну да. Главное тесты, а без функциональности клиент как-нибудь переживёт.

Если функциональность будет присутствовать только номинально, клиенту это тоже врядли понравится
(Кстати сейчас это — основная болезнь в нашей компании. Потому что не смотря на CMMI4 адекватного процесса разработки нет. А на самом деле это не такой уж тяжкий труд. Просто каждый на своём месте вместо постоянного п****ежа и пустых совещаний должен просто правильно делать свою работу. Конечно, обладая для этого соответствующей квалификацией.).
... << RSDN@Home 1.2.0 alpha rev. 677>>
Re[6]: Как Вы боретесь с ошибками?
От: IT Россия linq2db.com
Дата: 05.05.07 21:13
Оценка:
Здравствуйте, VGn, Вы писали:

IT>>UI в это большинство задач вписывается? 30 полей на форме с более менее зависимой логикой отображения и ты состаришься раньше, чем напишешь все возможные тесты. А когда напишешь, я добавлю ещё 10 полей. Только не в конец формы, а в случайном порядке с новой особенной логикой.


VGn>Утверждалась возможность, а не простота реализации, что тоже в конечном счёте вопрос инструментов.


Это как? В принципе сделать можно, но сложность не позволяет?

VGn>>>Просто конструировать надо сразу с расчётом на тестирование.

IT>>Конструировать надо не в расчёте на тестирование, а в расчёте на то, шоб оно работало как хочет клиент.

VGn>Нет. Так говорят малограмотные ПМы.


ПМы могут говорить что угодно. Но в данном случае обратное обычно утверждают юные начинающие архитекторы.

VGn>Это требования формулировать необходимо на основе пожеланий клиента.

VGn>Тесты — на основе требований.

Т.е. главное у нас всегда требования. А тесты — это всего лишь побочный эффект попытки добиться приемлемой сопровождаемости системы.

VGn>А код — удовлетворяющий этим тестам, а соответственно и всему остальному в обратном порядке.

VGn>Тогда мы всегда сможем трассировать пожелания-требования-тесты-код при изменении любой составляющей.
VGn>И в конечном счёте не будет обычного бардака с требованиями и реализацией.

Не понял как это связано. Когда меняются требования, то меняется код, а следовательно меняются и тесты. На бардак с требованиями это никак не влияет.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.